0

I am trying to convert the code below to Coldfusion. I am currently stuck on how to convert the "Transformer transformer = TransformerFactory.newInstance().newTransformer()" line to Coldfusion. Can anyone help convert this code?

The error message I get when using transformer = loader.create("javax.xml.transform.TransformerFactory").newInstance().newTransfo‌rmer();

Error casting an object of type org.apache.xalan.processor.TransformerFactoryImpl cannot be cast to javax.xml.transform.TransformerFactory to an incompatible type. This usually indicates a programming error in Java, although it could also mean you have tried to use a foreign object in a different way than it was designed. org.apache.xalan.processor.TransformerFactoryImpl cannot be cast to javax.xml.transform.TransformerFactory

 Document svgXmlDoc = ... File svgFile = File.createTempFile("graphic-", ".svg"); Transformer transformer = TransformerFactory.newInstance().newTransformer(); DOMSource source2 = new DOMSource(svgXmlDoc); FileOutputStream fOut = new FileOutputStream(svgFile); try { transformer.transform(source2, new StreamResult(fOut)); } finally { fOut.close(); } // Convert the SVG into PDF File outputFile = File.createTempFile("result-", ".pdf"); SVGConverter converter = new SVGConverter(); converter.setDestinationType(DestinationType.PDF); converter.setSources(new String[] { svgFile.toString() }); converter.setDst(outputFile); converter.execute(); 

Here is my code so far.

<cfscript> paths = arrayNew(1); paths[1] = expandPath("jar\avalon-framework-impl-4.2.0.jar"); paths[2] = expandPath("jar\batik-all-1.7.jar"); paths[3] = expandPath("jar\commons-io-1.3.1.jar"); paths[4] = expandPath("jar\commons-logging-1.0.4.jar"); paths[5] = expandPath("jar\fop-0.9.5.jar"); paths[6] = expandPath("jar\apache-log4j-1.2.15.jar"); paths[7] = expandPath("jar\xml-apis-ext.jar"); paths[8] = expandPath("jar\xmlgraphics-commons-1.3.1.jar"); paths[8] = expandPath("jar\javax.xml-1.3.4.jar"); loader = createObject("component", "javaloader.JavaLoader").init(paths); destinationtype = loader.create("org.apache.batik.apps.rasterizer.DestinationType"); svgconverter = loader.create("org.apache.batik.apps.rasterizer.SVGConverter"); // SVG available as a DOM object (created programatically by my program) svgXmlDoc = '<svg><text y="3.58in" x="1.5000in" id="fooddesc1" text-anchor="start" alignment-baseline="baseline">This is a test.</text></svg>'; // Save this SVG into a file (required by SVG -> PDF transformation process) f = loader.create("java.io.File"); svgFile = f.createTempFile("graphic-", ".svg"); transformer = loader.create("javax.xml.transform.TransformerFactory"); source2 = loader.create("javax.xml.transform.dom.DOMSource").init(svgXmlDoc); fOut = loader.create("java.io.FileOutputStream").init(svgFile); </cfscript> 
7
  • Just skimming the code, it should be almost the same ie transformer = loader.create("javax.xml.transform.TransformerFactory").newInstance().newTransformer();. Obviously you can split it into multiple calls if preferred. Commented Apr 3, 2015 at 20:04
  • I tried that but this is the error I receive. Error casting an object of type org.apache.xalan.processor.TransformerFactoryImpl cannot be cast to javax.xml.transform.TransformerFactory to an incompatible type Commented Apr 3, 2015 at 20:09
  • (Edit) Hm.. let me check something. Meanwhile, can you update your question with the full error message? Not everyone reads comments. Also, what version of CF are you running? Commented Apr 3, 2015 at 20:14
  • I am using ColdFusion 11. Just a FYI, I am not proficient in Java Commented Apr 3, 2015 at 20:17
  • (Edit) Okay. BTW, for CF10+ you do not need the javaLoader. A rip of that awesome project is now baked into CF10+. I am assuming it is a jar conflict. Can you tell me where you download those specific jars? I want to test with the same versions you are using. Commented Apr 3, 2015 at 20:31

1 Answer 1

1

Looks like the code you are translating is from this thread. I would suggest using the accepted answer instead. It is a bit simpler. However, you do not need to use the JavaLoader since you are running CF11. Starting from CF10, a rip of Mark Mandel's JavaLoader.cfc is baked into CF. Applications can load jars dynamically using this.javaSettings in the Application.cfc. The simplest option is to stick all of the jars in a separate directory, and point to that path in your application settings. Then you can load any of the classes with createObject().

 this.javaSettings = {LoadPaths = [ "/path/to/jars_folder/" ]}; 

Example:

transcoder = createObject("java", "org.apache.fop.svg.PDFTranscoder").init(); // load text into a reader and create the source input svgText = '<svg xmlns="http://www.w3.org/2000/svg"><text y="3.58in" x="1.5000in" id="fooddesc1" text-anchor="start" alignment-baseline="baseline">This is a test.</text></svg>'; reader = createObject("java", "java.io.StringReader").init(svgText); input = createObject("java", "org.apache.batik.transcoder.TranscoderInput").init(reader); // for demo purposes, create a unique file name outPath = ExpandPath("./"& createUUID() &".pdf"); fos = createObject("java", "java.io.FileOutputStream").init(outPath); output = createObject("java", "org.apache.batik.transcoder.TranscoderOutput").init(fos); transcoder.transcode(input, output); // ALWAYS close the stream fos.close(); 

The simple example above was tested with the following jars under CF10, so YMMV.

  • avalon-framework-4.2.0.jar
  • commons-io-1.3.1.jar
  • batik-all-1.7.jar
  • fop-0.9.5.jar
  • xmlgraphics-commons-1.3.1.jar
  • xml-apis-ext-1.3.04.jar



Original Exception

Error casting an object of type org.apache.xalan.processor.TransformerFactoryImpl cannot be cast to javax.xml.transform.TransformerFactory

I am not entirely sure what was causing the ClassCastException. I suspect it is some sort of a class loader issue. CF is already bundled with several of the libraries you are loading. At least one of the core jars contains another version of the TransformerFactory. Under CF10, the error goes away if you omit the javax.xml-1.3.4.jar (and commons-logging-1.0.4.jar). So somehow the various pieces are not playing well together under the custom class loader. Hence why things blow up when you call TransformerFactory.newInstance(). However, since you do not really need that class anyway, I did not look into it further...

Update:

FWIW, the error was definitely caused by a class loader conflict. The original code works fine if you omit javax.xml-1.3.4.jar (and commons-logging-1.0.4.jar).

If you look at the source for TransformerFactory.newInstance() you can see a call to FactoryFinder.find() which references different class loaders depending on the conditions. Since CF already includes the javax.xml.* package, I suspect some of the objects are being created by CF's class loader ie org.apache.xalan.processor.TransformerFactoryImpl, while others ie TransformerFactoryare created by a different class loader ie JavaLoader.

Class loaders are notoriously finicky. You have to follow certain rules or the objects created by one class loader will NOT be recognized by another - not even if they represent the exact same class. That seems to be what is happening here. You could probably fiddle with the parent or context class loader to get around it, but in this case it is simpler to just omit the javax.xml-1.3.4.jar.

Now having said all that ... I do not think you need the TransformerFactory code at all. It sounds like you already have a valid SVG string. Simply simply save it to a file with FileWrite() and move on with the rest of the code.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Leigh. I will get back on this next week and rethink my approach based on your findings.
Did a little more digging and found the cause of the original error. While you could use the original code with a few tweaks (see update) the other example is simpler. Assuming the results are the same, I would recommend using the simpler one instead.
Thanks Leigh. I ended up using your example and received more errors. I had to change out a couple jar files and it finally worked. Thanks again.
Welcome. It worked fine under CF10 (assuming we are using the same jars) so it is quite possible there are some differences in CF11. Out of curiosity, which ones did you end up using, so I can update the answer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.