You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@xml.apache.org by Andy Carlson <an...@hotmail.com> on 2001/11/09 17:08:02 UTC

JAXP (in)compatability between Xerces and Crimson

Hi all,

I've just spent quite a while tracking down a weird problem...

I'm running a servlet under Tomcat 4.0. The servlet includes Axis, which in 
this case is using the Xerces (1.4.3) parser. Everything works fine - no 
problem so far...

Now I try to run the same servlet on Tomcat 4.0 embedded in JBoss (2.4.1) 
and I get the following:-

java.lang.ClassCastException: 
org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
at 
javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:152)

So much for write once run anywhere.

Now this takes some tracking down but I now know how to fix it in my case: 
It turns out that the JBoss startup script sets a system property to specify 
org.apache.crimson.jaxp.DocumentBuilderFactoryImpl as the default DOM 
factory (and does similar for SAX). I dont know why it does this because 
removing the setting doesnt have any adverse effect which I can see and 
fixes the ClassCastException. Likewise, adding the same properties to the 
standalone Tomcat startup script causes the same error to occur in that 
environment.

So what's going on? (and who is to blame?)

Both JBoss and Tomcat use JAXP and Crimson and have their own copies of the 
jaxp.jar and crimson.jar. As far as I can tell, these copies all seem to use 
the same version of each library. Enabling the jaxp.debug property shows 
Crimson is being used just fine by the app servers internal code before my 
problem occurs.

Disassambling the DocumentBuilderFactory class which comes with Tomcat and 
JBoss reveals that there is no code at line 152...

Looking at the Xerces jar (and source) reveals that it has its own 
implementation of JAXP which differs from the one used by Crimson... and 
does indeed cast the newly created factory to DocumentBuilderFactory at line 
152.

Both Xerces and Crimson use META-INF/services to supply a default value for 
the DOM factory. Without the system property, the Servlet's copy of Xerces 
appears to 'win' in the servlet's context, create the Xerces factory and 
everything works OK.

Both versions of JAXP allow the System property to override the 
META-INF/services default.

So, what I think is happening is the following:-
- The Xerces DocumentBuilderFactory is the one running in the servlet 
context
- Its logic causes it to pick the Crimson DOM factory if the system property 
is present.
- It creates the Crimson DOM factory using Class.forName.newInstance
- Then it gets a ClassCastException. I presume this is because the Xerces 
JAXP has a different and incompatible idea of what the 
javax.xml.parsers.DocumentBuilderFactory class looks like - The Xerces one 
has an extra private static attribute and method over what the Crimson one 
has.

So what's the answer?

- at the moment the answer seems to be to avoid mixing Crimson and Xerces in 
the same context unless you have a very good understanding of how they are 
going to interact with each other - you might get away with it or you might 
(like me) spend a long time chasing strange problems.

... but this is bad news because it means that if my servlet uses an XML 
parser, I have to check whether the app server I'm deploying on is using 
another one in a way which is going to cause a conflict.

- For the future it would seem to be a better approach to agree on a single 
implementation of JAXP within Apache, put it in its own JAR and explicitly 
disallow (in the JAXP spec?) XML parser implementations from reimplementing 
all or part of JAXP in their own JARs.

Andy
----------------------------------------------------------------
Andy Carlson


_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp


---------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          general-unsubscribe@xml.apache.org
For additional commands, e-mail: general-help@xml.apache.org