Since I updated Xalan-Java 2.2D12, my servlet using javax.xml.transformer.* has spewed up the following error: Error: 500 Location: /diary/servlet/view Internal Servlet Error: javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found at javax.xml.transform.TransformerFactory.newInstance(Unknown Source) at org.unixuser.ueno.diary.processors.TransformerProcessor.process(Unknown Source) at org.unixuser.ueno.diary.DiaryBuilder.process(Unknown Source) at org.unixuser.ueno.diary.DiaryBuilder.build(Unknown Source) at org.unixuser.ueno.diary.servlet.View.doGet(Unknown Source) at javax.servlet.http.HttpServlet.service(HttpServlet.java) at javax.servlet.http.HttpServlet.service(HttpServlet.java) ... Of course, the SPI class org.apache.xalan.processor.TransformerFactoryImpl is located in <tomcat>/webapps/diary/lib/xalan.jar counted when the servlet container started. When I made a change in FactoryFinder#newInstance(String,ClassLoader) not to use the context ClassLoader for the current thread (i.e. always to call Class.forName), it worked as before. Regards,
Just a quick observation -- there isn't an official D12 release yet, though we were considering cutting one next week. FactoryFinder actually part of the xml-commons package rather than Xalan per se, though we currently incorporate it directly into our jarfile. A new version of xml-commons was recently released which reworked this class, partly due to ContextClassLoader not being available in JDK 1.1.8. You might want to try updating the commons classes, rebuild Xalan from scratch ("build clean" and then "build"), and see if this change solves your problem as well.
Sorry, I had missed reading the comment at the beginning of build.xml, although I'm using Xalan 2.2D12 checked out from CVS. Some time ago I checked out xml-commons together with xml-xalan, and rebuilt it from scratch. The situation however, didn't change unfortunately. It seems that Tomcat 3.2.3 coordinates the context ClassLoader regarding WEB-INF/classes, lib for each servlet, but doesn't relate it with the current thread, thus Thread#getContextClassLoader() returns the parent ClassLoader. What I would like to know is, why not go on using the current ClassLoader simply or otherwise respect the current ClassLoader when the context ClassLoader fails to load the provider class? Regards,
Check out the most recent version of xml-commons. I believe it does now use the current classloader when the context classloader isn't found.
Correct. But that doesn't help me with the problem. What I pointed out in the previous report is that I think it's safer to *use* current ClassLoader to load the implementation of TransformerFactory (here that is the Xalan's TransformerFactoryImpl) when the context ClassLoader fails to load it.
Could be. I don't know enough about the formal definitions of the behavior of the JAXP/TrAX APIs to have a valid opinion on that.
There are few big problems in tomcat3.2.3 related with Jaxp ! First, make sure you havethe Jdk12Interceptor ( which will set the thread class loader ). The real problem is that the files in lib/ will override the webapp classes - so if you want to change the parser or if a transformer is included in tomcat_home/lib - you can't change it. 3.3 solves this problem - and I don't think you can have multiple parsers/transformers in 3.2.3. I think 3.2.4 will include a recent JAXP, and so far the best workaround was to replace Jaxp.jar and parser.jar in lib with a current version of jaxp ( 3.2.3 still uses jaxp1.0 AFAIK )
I believe the code in xml-commons which prefers the context ClassLoader over the current ClassLoader is the correct behavior. Changing the order would break other situations. The context ClassLoader in Tomcat is probably set wrong. BTW, if you are using crimson as your parser, then the latest version is crimson 1.1.3 and there is only a single jar file: crimson.jar.