14 March 2006

Classpath Gymnastics: JAXP, Java5 and JBoss


Started to get a problem with JBoss and Java5. Not sure what caused it to _start_ occurring. I'm using isolated EAR deployments and excluding all xml-apis and xerces jars from my EARs since all this stuff should be provided by the java runtime.



Anyway, started to get this error:


XPathFactory#newInstance() failed to create an XPathFactory for the default object model: http://java.sun.com/jaxp/xpath/dom with the XPathFactoryConfigurationException: javax.xml.xpath.XPathFactoryConfigurationException: No XPathFctory implementation found for the object model: http://java.sun.com/jaxp/xpath/dom



It turns out you can enable jaxp debugging with the following system property:
-Djaxp.debug=true

This resulted in some useful messages:


08:17:52,874 INFO [STDOUT] JAXP: using thread context class loader (org.jboss.util.loading.DelegatingClassLoader@11c9fcc) for search
08:17:52,875 INFO [STDOUT] JAXP: Looking up system property 'javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom'
08:17:52,875 INFO [STDOUT] JAXP: The property is undefined.
08:17:52,876 INFO [STDOUT] JAXP: found null in $java.home/jaxp.properties
08:17:52,876 INFO [STDOUT] JAXP: no META-INF/services/javax.xml.xpath.XPathFactory file was found
08:17:52,876 INFO [STDOUT] JAXP: attempting to use the platform default W3C DOM XPath lib
08:17:52,876 INFO [STDOUT] JAXP: instanciating org.apache.xpath.jaxp.XPathFactoryImpl
08:17:52,877 INFO [STDOUT] JAXP: failed to instanciate org.apache.xpath.jaxp.XPathFactoryImpl
08:17:52,880 INFO [STDOUT] java.lang.ClassNotFoundException: No ClassLoaders found for: org.apache.xpath.jaxp.XPathFactoryImpl



Looking at the JAXP sources revealed the problem. In the source for Java5 javax.xml.xpath.XPathFactoryFinder we see this:


debugPrintln("attempting to use the platform default W3C DOM XPath lib");
return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl");


In the log, we see this message: instanciating org.apache.xpath.jaxp.XPathFactoryImpl

com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl != org.apache.xpath.jaxp.XPathFactoryImpl



So why is this? Looking at the JBoss endorsed directory at /lib/endorsed we can see it contains xml-apis.jar which contains javax.xml.xpath.XPathFactoryFinder which overrides the Java5 version. That overridden version tries to lookup org.apache.xpath.jaxp.XPathFactoryImpl but that doesn't exist in Java5; it was renamed. And since I've excluded all xml jars from my EARs, I don't have that class anywhere.



Of course, I'm not the first to have this problem.


I simply renamed the lib/endorsed directory and restarted. This seemed to work, although based on the second link above, there might be more work to do later.

1 comment:

kahnpsu said...

It may also be of note if you are in the situation where you do not have control of the appserver/common/endorsed/ files that you can also fix this problem by downloading the xalan-j_2_7_0-bin.zip distro and extracting the xalan.jar into your WEB-INF/lib folder of your app.

This will add the older implementation to your classpath if you aren't allowed to modify your appserver.

Additional Note - This problem also exists verbatim in Tomcat 5.0.22 and Java 1.5