How to use a different version of Xerces in an ear than is in JBoss Enterprise Application Platform (EAP)?
Environment
- JBoss Enterprise Application Platform(EAP)
- 4.2.0
- 4.3.0
-
xercesImpl-2.8.0.jar in the classpath
-
Set isolation = true in $JBOSS_HOME/server/<CONFIG>/deploy/ear-deployment.xml
Issue
- Load ear in diffrent classloader
- The following exception is thrown by spring when deployed with the following configuration: Caused by: java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
- how to config jboss to load multiple ear in different class loader
Resolution
- If the code calling Xerces is inside of a war, then this property must be set to override the Xerces in JBoss
- -Dorg.apache.catalina.loader.WebappClassLoader.SYSTEM_CL_DELEGATION=false in JAVA_OPTS
- Note this option is not available until >= JBoss 4.2.0.GA_CP06 or >= JBoss 4.3.0.GA_CP04 [2]
-
The ear should be scoped/isolated [1].
-
Add the loader-repository as shown below to the ear/META-INF/jboss-app.xml. The xerces.examples.jboss.com:loader=xerces-test.ear should be a unique string, usually your ear name. The java2ParentDelegation=false tells it to use the packaged jars before looking in the jboss lib. Also, you should not include the xml-apis.jar as it contains javax classes which are included in the Java SE.
<?xml version="1.0"?> <jboss-app> <loader-repository> xerces.examples.jboss.com:loader=xerces-test.ear <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> </jboss-app>
-
Root Cause
-
xml-apis.jar cannot be packaged because these are javax classes that are contained in the Java SE
-
The initial JBoss configuration for JBossWeb is such that the JBossWeb classloader is used instead of the JBoss UnifiedClassLoader. This requires that the property org.apache.catalina.loader.WebappClassLoader.SYSTEM_CL_DELEGATION be set to false in order for JBossWeb to use the packaged Xerces over the JBoss packaged version.
- When there are multiple jars in the classpath with the same class, JBoss will use the one that gets loaded first for all classes that request it.
- By default ears are not isolated or scoped. To have an ear use a different version of a jar / class than is pacakged in JBoss lib, the ear must be isolated/scoped by specifying a unique loader repository in the jboss-app.xml. Also the java2ParentDelegation must be set to false so that JBoss will look in the ear's loader respository before looking in the JBoss loader repository (JBoss lib directory, and classes loaded in the UnifiedClassLoader )
[1] http://www.jboss.org/community/wiki/ClassLoadingConfiguration
Diagnostic Steps
- See what jars are being packaged in the application (ear)
- See if the code that is calling Xerces is inside of a war [2]
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments