Hi,
A plugin adds a 3rd party dependency (dep.jar) which uses the javax.xml.parsers.DocumentBuilderFactory:
dep.jar source:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance( );
It raises the following exception:
java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory
The object instance returned by the expresison on the right DocumentBuilderFactory.newInstance( ) is of type:
org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
and the object instance returned is loaded with the JIRA tomcat webapp class loader described below:
WebappClassLoader context: /jira delegate: false repositories: /WEB-INF/classes/ ----------> Parent Classloader: org.apache.catalina.loader.StandardClassLoader@7260a330
on the other hand the javax.xml.parsers.DocumentBuilderFactory is present twice in the plugin:
The class loader of the third party library (dep.jar) is:
class org.apache.felix.framework.ModuleImpl$ModuleClassLoader
Therefore it looks like the expression on the right DocumentBuilderFactory.newInstance( ) loads an object with the Tomcat webapp class loader for JIRA whereas the expression on the left DocumentBuilderFactory factory
uses the Plugin framework (Felix) class loader which is not allowed by Java.
One solution might be by removing the xml-apis-1.0.b2.jar dependency which is brought by the JIRA API with scope compile. In such case, the javax.xml.parsers.DocumentBuilderFactory would be loaded by the provided one by Java (rt.jar). However, it looks like it is not possible because excluding the xml-apis-1.0.b2.jar library causes a org.w3c.dom.Document not found exception. The missing Document class is declared as Private-Package on the transformed plugin META-INF.MF manifest. It means it cannot be imported (Package-Import) and the it has to be added into the plugin jar during the packaging stage, so adding it as dependency with compile scope seems to be the only one way.
Another approach would be configure the DocumentBuilderFactory via plugin by adding <jmvArgs> in the <configuration> section in the pom.xl, but as the configuration is global for the application, then JIRA crashes.
How could it be resolved and avoid the ClassCastException?
Thanks in advance,
Pablo.
Community moderators have prevented the ability to post new answers.
Hi Pablo,
The reason may be due to the xerces package being boot delegated. Thus all the plugins will load org.apache.xerces.jaxp.DocumentBuilderFactoryImpl class from the bundled jar in WEB-INF/lib
You may want to refer to https://ecosystem.atlassian.net/browse/PLUG-594 and https://ecosystem.atlassian.net/browse/PLUG-502 for more details.
Akeles, do you know how to make it work? Of course, the expression on the right is boot delegated and it uses the JIRA web app class loader. But, how would be possible to force the expression on left to be boot delegated too?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Akeles,
I have tried that but did not work, it gives me "java.lang.ClassNotFoundException: org.w3c.dom.Node
at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:772)". I also tried to remove:
<dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>1.3.04</version> <scope>provided</scope> </dependency>
and the exclusion:
<exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions>
and i get again "java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory"
Thank you,
Regards
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I found out the solution: <dependency> <groupId>org.apache.abdera</groupId> <artifactId>abdera-parser</artifactId> <version>1.1.3</version> <exclusions> <exclusion> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </exclusion> <exclusion> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.abdera</groupId> <artifactId>abdera-core</artifactId> <version>1.1.3</version> <exclusions> <exclusion> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.abdera</groupId> <artifactId>abdera-i18n</artifactId> <version>1.1.3</version> <exclusions> <exclusion> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </exclusion> </exclusions> </dependency> Regards
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Congrats ;)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for sharing your solution. A question, how do you arrive to exclude jaxen artifact?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It did not work for me because the 3rd party dependency require an older version of the xml-apis
I placed the extractDependencies together with the productVersion
<configuration> <extractDependencies>false</extractDependencies> <productVersion>${jira.version}</productVersion> <productDataVersion>${jira.version}</productDataVersion>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Pablo Beltran [Kinto Soft] and @Akeles ,
Im also getting "java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory" when added org.apache.abdera as dependency to pom. I'have tried to follow your tips Pablo, adding:
<dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>1.3.04</version> <scope>provided</scope> </dependency>
and excluding it from abdera dependency:
<dependency> <groupId>org.apache.abdera</groupId> <artifactId>abdera-parser</artifactId> <version>1.1.3</version> <exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions> </dependency>
But then i get "java.lang.ClassNotFoundException: org.w3c.dom.Node at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:772)" and i can't understand why.
Where did you insert <extractDependencies>true</extractDependencies> ?
Kind regards,
Fábio Antunes
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The suggestion I found was to use the bundled XML classes within JIRA instead of specifying them with compile scope in pom.xml.
However, I did not verify if it works as we decided to go for an easier alternative than to use XML.
It will be very useful if you can post the verified solution.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Community moderators have prevented the ability to post new answers.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.