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/
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:
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
@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..
@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
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
@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>
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
@Murray,
You are very welcome :) I am glad you got it sorted out.
Post a Comment