Sunday, December 16, 2007

How to use newer version of iText without breaking ColdFusion


Update January 16, 2010: iText 5.0.0 contains a significant change that affects ColdFusion users. See ColdFusion + iText 5.0.0 (Good things come in *new* packages)


After writing a few entries about iText and ColdFusion, I realized many of the examples will require a newer version of iText jar than the one that ships with MX7 or ColdFusion 8. So I am writing the instructions here for easy reference.

Thanks to the genius of Mark Mandel you can load external jars (like a newer version of iText) within ColdFusion using his JavaLoader.cfc.

1. Download the iText-2.0.7.jar (or newer) available at sourceforge.net

2. Download and install the JavaLoader.cfc available at javaloader.riaforge.org/

MX users see also Using a Java URLClassLoader in CFMX Can Cause a Memory Leak



UPDATE: Though it is mentioned above and in many of the code comments, I may not have stated this point as strongly as I could have. So I would like to reiterate. MX users that are running the JavaLoader.cfc must read the article Using a Java URLClassLoader in CFMX Can Cause a Memory Leak.

In summary it is recommended that you store a single instance of the javaLoader in the server scope, rather than creating a new object each time. This prevents a memory leak caused by a bug in ColdFusion MX. I do not know if this bug exists in ColdFusion 8.


As a point of reference, here is where I installed the files on my local computer. You will be seeing these paths in most of my examples. But you can install the files to a different location if you wish.


<!--- the "iText" directory contains all of my iText examples --->
C:\CFusionMX7\wwwroot\iText\iText-2.0.7.jar

<!--- the "com" folder contains all of my components (cfc's) --->
C:\CFusionMX7\wwwroot\com\javaloader\JavaLoader.cfc
C:\CFusionMX7\wwwroot\com\javaloader\JavaProxy.cfc
C:\CFusionMX7\wwwroot\com\javaloader\lib\*.*

7 comments:

Anonymous,  August 4, 2008 at 5:53 PM  

I really love this iText/CF integration series. But I'll want to give you a challenge: how to create PNG(or JPG) image from a PDF file?
Cheers

cfSearching August 5, 2008 at 6:06 AM  

@Marco Antonio,

For ColdFusion 8 it would be the cfpdf tag with action="thumbnail". For MX 7 my guess would be to use JPedal www.jpedal.org/. Their home page says it included in ColdFusion 8.

"We are delighted that Adobe Systems Incorporated©, the inventors of PDF, have chosen JPedal as the PDF viewer in ColdFusion 8.

Though they do not say it exactly, it could be what is used for cfpdf action="thumbnail". I have not had a chance to look for it yet, but I know there is a thumbnail example somewhere on their site..

cfSearching August 5, 2008 at 6:57 AM  

@Marco Antonio,

It is JPedal. I found this blog entry by Dan G. Switzer, II. about using JPedal with CF8.

Assuming no conflicts, I am guessing it should work with MX 7 too. As long you have the JPedal jar loaded, and the necessary image encoders registered.

UDF-for-converting-a-PDF-page-to-Images-using-CF8-and-Java

Anonymous,  August 29, 2008 at 4:16 AM  

Thanks for all the great info on your blog about iText.

Having done a bit of work using the built-in iText for MX7 I am now experimenting with using the latest version (2.1.3) utilising the javaloader.

All seems to work in that I am creating pdfs without errors.

However, when I display the version number using

iTextVers = document.getVersion();

I get "iText by lowagie.com (r1.02b;p128)" which is the same as the built-in version!

Here are the relevant bits of code:

paths = arrayNew(1);
paths[1] = "#request.GlobalCFLibPath#cfc\javaclass\iText-2.1.3.jar";

//create the loader
loader = createObject("component", "#request.GlobalCFCLib#.JavaLoader").init(paths);

document = loader.create("com.lowagie.text.Document");
// as opposed to the built-in version which was:
//document = CreateObject("java", "com.lowagie.text.Document");

document.init();

{etc}

So, am I correctly instantiating the javaloaded version or am I somehow still using the built-in version as the version number would seem to indicate? Is there some other way I can test which library I am using?

Any help would be gratefully appreciated.

Thanks,
Murray

cfSearching August 29, 2008 at 6:15 AM  

@Murray,

From the snippets, the instantiation looks correct. But if you are seeing version "r1.02b;p128" it strongly suggests the object was not created with the newer jar. I would double check the code. Make sure you have not missed any createObject(...) references. That mistake catches me once in a while.

You could also test for one of the newer methods that did not exist in the MX 7 version. Here is an example. The code works with a newer version of iText, but throws an error when using the built in MX 7 jar:



<cfscript>
// WARNING: do not do this on production. store the javaloader
// in the server scope to avoid a memory leak
paths = arrayNew(1);
paths[1] = expandPath("/dev/iText/iText-2.0.7.jar");
loader = createObject("component", "javaloader.JavaLoader").init( paths );
document = loader.create("com.lowagie.text.Document").init();
WriteOutput("version="& document.getVersion() &"<br>");
document.setMarginMirroring( javacast("boolean", true) );
document.close();
WriteOutput("success<br>");
</cfscript>


<cfscript>
// MX 7 Example
// Throws errror: The selected method setMarginMirroring was not found.
document = createObject("java", "com.lowagie.text.Document").init();
WriteOutput("version="& document.getVersion() &"<br>");
document.setMarginMirroring(javacast("boolean", true));
document.close();
WriteOutput("success<br>");
</cfscript>

Anonymous,  August 29, 2008 at 2:27 PM  

Thank you so much for your help. I went back to first principles and tested everything from one folder and it worked.

So, the reason for my problem was very basic - I had simply omitted to copy the \lib folder for javaloader to my cfc repository! Doh!

No error was thrown so I didnt notice in my sleepy state.

Thanks again for your help. I can now continue to build my iTextCFC.

Regards,
Murray

cfSearching August 29, 2008 at 2:38 PM  

@Murray,

You are very welcome :) I am glad you got it sorted out.

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep