Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Using XML from 3rd party libraries in JIRA plugins

Pablo Beltran
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 9, 2015

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:

  • rt.jar  (via Java)
  • xml-apis-1.0.b2.jar (via JIRA API dependency).

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.

 

5 answers

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Akeles
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 10, 2015

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.

 

 

 

Pablo Beltran
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 12, 2015

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?

0 votes
Fábio Antunes September 10, 2015

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:

 

&lt;dependency&gt;
    &lt;groupId&gt;xml-apis&lt;/groupId&gt;
    &lt;artifactId&gt;xml-apis&lt;/artifactId&gt;
    &lt;version&gt;1.3.04&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
&lt;/dependency&gt;

 and the exclusion:

&lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;xml-apis&lt;/groupId&gt;
            &lt;artifactId&gt;xml-apis&lt;/artifactId&gt;
        &lt;/exclusion&gt;
  &lt;/exclusions&gt;

 

 and i get again "java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory"

Thank you,
Regards 

Fábio Antunes September 10, 2015

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

Pablo Beltran
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 10, 2015

Congrats ;)

Akeles
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2015

Thanks for sharing your solution. A question, how do you arrive to exclude jaxen artifact?

0 votes
Akeles
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 10, 2015

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

 

&lt;configuration&gt;
          &lt;extractDependencies&gt;false&lt;/extractDependencies&gt;
          &lt;productVersion&gt;${jira.version}&lt;/productVersion&gt;
          &lt;productDataVersion&gt;${jira.version}&lt;/productDataVersion&gt;



0 votes
Fábio Antunes September 10, 2015

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:

&lt;dependency&gt;
	&lt;groupId&gt;xml-apis&lt;/groupId&gt;
	&lt;artifactId&gt;xml-apis&lt;/artifactId&gt;
	&lt;version&gt;1.3.04&lt;/version&gt;
	&lt;scope&gt;provided&lt;/scope&gt;
&lt;/dependency&gt;

and excluding it from abdera dependency:

&lt;dependency&gt;
	&lt;groupId&gt;org.apache.abdera&lt;/groupId&gt;
	&lt;artifactId&gt;abdera-parser&lt;/artifactId&gt;
	&lt;version&gt;1.1.3&lt;/version&gt;
	&lt;exclusions&gt;
		&lt;exclusion&gt;
			&lt;groupId&gt;xml-apis&lt;/groupId&gt;
			&lt;artifactId&gt;xml-apis&lt;/artifactId&gt;
		&lt;/exclusion&gt;
	&lt;/exclusions&gt;
&lt;/dependency&gt;

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 

0 votes
Akeles
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 12, 2015

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.

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events