Bug 4574

Summary: javax.xml.transformer.FactoryFinder#newInstance fails when called from servlets
Product: XmlCommons - Now in JIRA Reporter: Daiki Ueno <ueno>
Component: JAXPAssignee: Commons Developers Mailing List <commons-dev>
Status: NEW ---    
Severity: normal Keywords: APIBug
Priority: P3    
Version: 1.x   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Daiki Ueno 2001-11-01 14:15:28 UTC
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,
Comment 1 Joe Kesselman 2001-11-02 05:52:13 UTC
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.
Comment 2 Daiki Ueno 2001-11-02 19:02:29 UTC
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,
Comment 3 Joe Kesselman 2001-11-05 13:52:58 UTC
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.
Comment 4 Daiki Ueno 2001-11-07 03:56:16 UTC
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.
Comment 5 Joe Kesselman 2001-11-07 07:04:11 UTC
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.
Comment 6 Costin Manolache 2001-11-07 09:22:54 UTC
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 )
Comment 7 Edwin Goei 2001-11-07 12:46:16 UTC
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.