13 Replies Latest reply on Jan 7, 2016 11:46 AM by Joseph Fouts

    TransformerFactory.newTransformer ERROR

    Joseph Fouts Novice

      Running the following code with JBoss 7.1 worked fine but now with Wildfly 9 I am getting this exception ->        javax.xml.transform.TransformerConfigurationException: Translet class loaded, but unable to create translet instance.

       

      (snippet from code)

      import javax.xml.transform.Transformer;

      import javax.xml.transform.TransformerException;

      import javax.xml.transform.TransformerFactory;

       

      transformer = tfactory.newTransformer(xslSource);

       

       

      Here is the full stacktrace:

       

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) javax.xml.transform.TransformerConfigurationException: Translet class loaded, but unable to create translet instance.

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(Unknown Source)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(Unknown Source)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(Unknown Source)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(Unknown Source)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at __redirected.__TransformerFactory.newTransformer(__TransformerFactory.java:128)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.lidp.enterprise.reporting.converter.BasicConverter.transformBasicXSL(BasicConverter.java:91)

      14:40:20,894 ERROR [stderr] (Thread-17 (HornetQ-client-global-threads-1244233300)) at com.lidp.enterprise.reporting.process.module.RPGenerator.produceCSV(RPGenerator.java:244)

       

       

      Any idea what might be going on here?

      Not sure what the line with the ___redirected__TransformerFactory is doing but I am wondering if this could be the culprit.

       

      Any help is greatly appreciated.

        • 1. Re: TransformerFactory.newTransformer ERROR
          Joseph Fouts Novice

          Does any of the JBoss experts have any idea what might be going on with calls to the TransformerFactory ?

          I found online that someone  suggested that JBoss is now redirecting the TransformerFactory class to another version.

           

          Here is the link:

          http://stackoverflow.com/questions/25768344/set-javax-xml-transform-transformerfactory-in-wildfly-8-1

           

           

          I tried using the system properties like he suggested but it still gave me the same error.

           

          I need to get this working by the end of the month in a production environment so any help would be greatly appreciated.

           

          Thanks!!!

          • 2. Re: TransformerFactory.newTransformer ERROR
            David Lloyd Master

            I think the answer could be as simple as, the thread context class loader might not be set when you are calling TransformerFactory.newTransformer().  Can you check to see what the value of java.lang.Thread#getContextClassLoader() for the current thread is, at the time you call that method?  Maybe try setting it explicitly to getClass().getClassLoader()?

            • 3. Re: TransformerFactory.newTransformer ERROR
              Joseph Fouts Novice

              Hi David thanks for your help.

               

              Not sure exactly what you mean.

               

              I am currently getting the instance of the TransformerFactory with the following statement:

               

              tfactory = TransformerFactory.newInstance();

               

              Not sure how to set the classLoader() explicitly.

               

              Can you please give me some hints on how to do this?

               

              Thanks.

              • 5. Re: TransformerFactory.newTransformer ERROR
                David Lloyd Master

                That class loader is not used in the code which is generating the exception.

                • 6. Re: TransformerFactory.newTransformer ERROR
                  David Lloyd Master

                  You must set the context class loader: Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

                  • 7. Re: TransformerFactory.newTransformer ERROR
                    Joseph Fouts Novice

                    So I added the following line to my code:

                     

                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

                     

                    Remaining code:

                     

                       tfactory = TransformerFactory.newInstance();

                      ResourceResolver rr = new ResourceResolver();

                      tfactory.setURIResolver(rr);

                                   

                      transformer = tfactory.newTransformer(xslSource);

                            

                    I still get the same exception:

                     

                     

                    3:49:30,712 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) javax.xml.transform.TransformerConfigurationException: Translet class loaded, but unable to create translet instance.

                    13:49:30,714 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(Unknown Source)

                    13:49:30,714 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(Unknown Source)

                    13:49:30,715 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(Unknown Source)

                    13:49:30,715 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(Unknown Source)

                    13:49:30,716 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at __redirected.__TransformerFactory.newTransformer(__TransformerFactory.java:128)

                    13:49:30,716 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.lidp.enterprise.reporting.converter.BasicConverter.transformBasicXSL(BasicConverter.java:92)

                    13:49:30,717 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.lidp.enterprise.reporting.process.module.RPGenerator.produceFO(RPGenerator.java:265)

                    13:49:30,717 ERROR [stderr] (Thread-2 (HornetQ-client-global-threads-491363990)) at com.lidp.enterprise.reporting.process.module.RPGenerator.generateReportFormatTypes(RPGenerat

                     

                     

                    Did I put the code in the correct place?

                     

                    I still think it has something to do with the __redirected_TransformerFacotry line.

                     

                    Any other ideas.  As I mentioned this same code works with JBoss Eap 6.2.

                     

                    Thanks.

                    • 8. Re: TransformerFactory.newTransformer ERROR
                      Joseph Fouts Novice

                      David,

                       

                      I found this similar thread regarding the same problem that I am having.

                      Could you verify if this bug has been fixed?

                       

                      jboss-modules LinkageError / Translet class loaded, but unable to create translet instance.

                       

                       

                      Thanks.

                      • 9. Re: TransformerFactory.newTransformer ERROR
                        David Lloyd Master

                        The lack of line numbers obfuscates the problem a little bit.  The "__redirected" part that you see is the JBoss Modules mechanism for allowing multiple implementations of the various JAXP APIs.  Here's a breakdown of what happens:

                        1. "tfactory = TransformerFactory.newInstance();" <- this line calls into the JAXP API, which is pre-configured by the container to reference __redirected.__TransformerFactory, a class in the JBoss Modules JAR.
                        2. An instance of this class is generated.  In the constructor of this class, the the current thread's context class loader is used to locate the "real" implementation class, by way of searching for the first occurrence of a resource named "META-INF/services/javax.xml.transform.TransformerFactory". The thread context class loader is generally set to the class loader of the deployment module (the line of code you added is extra assurance of this, and the fact that it didn't change the result is evidence that this was already working correctly).
                        3. "tfactory.setURIResolver(rr);" <- this line calls into the __redirected.__TransformerFactory#setURIResolver method, which in turn calls the "real" setURIResolver method on the actual TransformerFactory (which is a com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl - this is the JDK's implementation, not the one from your xalan.jar, which is what I'll refer to as "problem #1").
                        4. "transformer = tfactory.newTransformer(xslSource);" <- this line also calls into the __redirected class, which in turn calls the "real" newTransformer method on the actual implementation.
                        5. Through various means, this results in a nested call to "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#defineTransletClasses()", a method which generates some class files which are used internally by the factory.  This is failing at what appears to be an unknown location; however, we can narrow this down a bit. There are four possible places that a TransformerConfigurationException may be thrown from this method.  Only one of them throws an exception which results in the string "Translet class loaded, but unable to create translet instance.", and that is if one of the generated classes has a linkage error (this is what I'll refer to as "problem #2").  In other words, the class loader into which the translet class was being generated (i.e. your WAR application's class loader) for some reason does not have direct access to some class that is needed by one or more of the generated classes.  Unfortunately the JDK code hides the caused-by exception message and stack trace, making this problem more difficult to solve.

                         

                        I think that "problem #1" is your primary problem: you want to get an instance of TransformerFactory out of your xalan.jar, but instead you're getting the one out of the JDK.  This is probably as simple as a class loader ordering problem: you need the WAR's xalan.jar to appear before the JDK's JAXP API (which it should already do in WildFly 8.1 I think).

                         

                        The best way to thoroughly examine what's going on with your class loader ordering is to pop open the JBoss Modules MBean in JConsole or your favorite JMX tool, and have a look into the "service module loader", which should contain a module named approximately similarly to your WAR.  Within this MBean should be a complete and exhaustive description of what dependencies are searched and in what order, and this should show why you are not getting the TransformerFactory you want.

                         

                        Alternatively you can do as Tomaž has suggested and just specify the class loader of the implementation that you want - or even perhaps instantiate it directly using a "new" expression - both of which should suffice to work around "problem #1".  I think "problem #2" is somewhat more involved though and might require some fairly tricky debugging.  One problem at a time!

                        • 10. Re: TransformerFactory.newTransformer ERROR
                          David Lloyd Master

                          Yes it is possible that the problem is the one described in WFCORE-519.  The only way to find out for sure is testing though.

                          • 11. Re: TransformerFactory.newTransformer ERROR
                            Joseph Fouts Novice

                            David can you or Tomaz show me how I would specify the class loader of the implementation that I want?

                            I am confused and I really am not sure how to do this.  I looked at the link that Tomaz provided but I am still not clear on what I have to do.

                             

                            So if I want the TransfoerFactory from the xalan.jar then how do I get it?  

                             

                            Is it this line that is going to have to change?

                            // setup transformer

                            tfactory = TransformerFactory.newInstance();

                             

                            Thanks.

                            • 12. Re: TransformerFactory.newTransformer ERROR
                              David Lloyd Master

                              There are two ways.  Assuming you want "org.apache.xalan.xsltc.trax.TransformerFactoryImpl" from your xalan.jar, either do this:

                               

                              tfactory = TransfomerFactory.newInstance("org.apache.xalan.xsltc.trax.TransformerFactoryImpl", org.apache.xalan.xsltc.trax.TransformerFactoryImpl.class.getClassLoader());

                               

                              or just do this:

                               

                              tfactory = new org.apache.xalan.xsltc.trax.TransformerFactoryImpl();

                              • 13. Re: TransformerFactory.newTransformer ERROR
                                Joseph Fouts Novice

                                Thanks David I was finally able to get it to work using your example.

                                 

                                I used the following code to get to the xalan implementation that I wanted:

                                 

                                Class<?> clazz = Class.forName("org.apache.xalan.processor.TransformerFactoryImpl");

                                TransformerFactory tfactory = (TransformerFactory) clazz.newInstance(); 

                                 

                                This entire process is to eventually create an PDF file.

                                The above code that was fixed was code that was used for creating a FO object.

                                 

                                I am now running into the similar problem when I try using FOP to create a PDF.

                                My code for the PDF generation is similar to the code from my first problem.

                                 

                                       Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdfContent);

                                 

                                       Class<?> clazz = Class.forName("org.apache.xalan.processor.TransformerFactoryImpl");

                                       TransformerFactory tfactory = (TransformerFactory) clazz.newInstance(); 

                                        

                                       Transformer transformer = tfactory.newTransformer();

                                       Source src = new StreamSource(foFile);

                                 

                                        Result res = new SAXResult(fop.getDefaultHandler());

                                -->    transformer.transform(src, res);

                                 

                                The above line is causing the exception.

                                 

                                Again as you can see in this stack trace the __redireced__XMLReaderFactory is being used.

                                 

                                I am not sure what should I implement myself on this one.

                                 

                                Would you have any ideas what might have to do to get by this problem.?

                                 

                                Your help is appreciated.

                                 

                                 

                                 

                                 

                                Here is the stack trace:

                                 

                                at org.hornetq.core.client.impl.ClientConsumerImpl.access$500(ClientConsumerImpl.java:56)
                                at org.hornetq.core.client.impl.ClientConsumerImpl$Runner.run(ClientConsumerImpl.java:1251)
                                at org.hornetq.utils.OrderedExecutorFactory$OrderedExecutor$1.run(OrderedExecutorFactory.java:104)
                                at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [rt.jar:1.8.0_66]
                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.8.0_66]
                                at java.lang.Thread.run(Unknown Source) [rt.jar:1.8.0_66]

                                Caused by: java.lang.RuntimeException: java.lang.IncompatibleClassChangeError: Class org.apache.fop.fo.FOTreeBuilder does not implement the requested interface org.xml.sax.ContentHandler

                                ... 128 more

                                Caused by: java.lang.IncompatibleClassChangeError: Class org.apache.fop.fo.FOTreeBuilder does not implement the requested interface org.xml.sax.ContentHandler

                                at org.apache.xalan.transformer.TransformerIdentityImpl.setDocumentLocator(TransformerIdentityImpl.java:887) [xalan-2.7.0.jar:]
                                at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startDocument(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startDocument(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.startEntity(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.startDocumentParsing(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) [rt.jar:1.8.0_66]
                                at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) [rt.jar:1.8.0_66]
                                at __redirected.__XMLReaderFactory.parse(__XMLReaderFactory.java:176) [jboss-modules.jar:1.4.3.Final]
                                at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484) [xalan-2.7.0.jar:]
                                at com.lidp.enterprise.reporting.converter.PDFConverter.generate(PDFConverter.java:54) [LIDP_ADMI_Enterprise.jar:]
                                at com.lidp.enterprise.reporting.process.module.RPGenerator.producePDF(RPGenerator.java:175) [LIDP_ADMI_Enterprise.jar:]