2 Replies Latest reply on Aug 2, 2011 5:52 AM by patrycja

    Deployment issues when WAR package includes xml-apis.jar

    null null Newbie

      Hi all,


      We are preparing to migrate several applications from Weblogic, Tomcat and Websphere to JBoss 5. Many applications are built with Maven, and a result of this is that some of our WAR packages get xml-apis.jar (the JAXP API) as a transitive dependency from some other libraries.


      When we do have this packaged, we get the following stack trace when the application is deployed:


      2010-01-07 11:54:10,127 INFO  [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (main) deploy, ctxPath=/foo
      2010-01-07 11:54:10,169 ERROR [org.apache.commons.digester.Digester] (main) Digester.getParser:
      java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
              at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:128)
              at org.apache.tomcat.util.digester.Digester.getFactory(Digester.java:499)
              at org.apache.tomcat.util.digester.Digester.getParser(Digester.java:704)
              at org.apache.tomcat.util.digester.Digester.getXMLReader(Digester.java:978)
              at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1643)
              at org.apache.catalina.startup.TldConfig.tldScanStream(TldConfig.java:518)
              at org.apache.catalina.startup.TldConfig.tldScanJar(TldConfig.java:476)
              at org.apache.catalina.startup.TldConfig.execute(TldConfig.java:301)
              at org.apache.catalina.core.StandardContext.processTlds(StandardContext.java:4540)
              at org.apache.catalina.core.StandardContext.start(StandardContext.java:4308)
              at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:310)
              at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:142)
              at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
              at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118)
              at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)



      The WEB-INF/lib contains only xml-apis.jar. It does not contain XercesImpl or any other JAXP implementation. That leads to a different ClassCastException and is already noted in  https://jira.jboss.org/jira/browse/JBAS-7210.


      My undertanding on why this is happening is that JAXP (javax.xml.parsers.SAXParserFactory)is being loaded in one classloader, and the implementation (org.apache.xerces.jaxp.SAXParserFactoryImpl) is in a different classloader. I also understand that the removal of xml-apis.jar will fix the problem, and is the most appropriate solution. Packaging up classes already defined by the JDK is not just poor form, it probably wont work anyway given that stuff needs to go in an endorsed directory, if it really needs to be changed.


      What I'm interested in is that these applications actually deploy and work in Weblogic, Tomcat and Jetty, but not JBoss. My reading on the subject suggests those other products will ignore classes in the javax packages when they are in the application's classloader, so although packaging up xml-apis.jar is wrong (in that it won't work as may be intended), it will not fail the deployment and the container simply ignores them - using the JDK versions instead.


      I'm interested in your thoughts as to JBoss's classloader at deployment time. Should JBoss ignore javax.* classes located in the application classloader, as is the case with the other app servers I've tested against? Or is this a grey region where there is no guarantee that a server should ignore packaged versions of JRE (and possible JEE) libraries?