Atlas-package includes extra class files on one machine, causing LinkageErrors, but not on another

Summary: When I run atlas-package on the same BitBucket plugin source project folder on two different machines, one machine's .jar (and the "target/classes" directory in the project folder) contains .class files for all the dependencies, while the other machine's .jar (and the same associated directory) contains only the .class files for the actual .java files in the project. The .jar file with the extra .class files leads to errors when trying to enable it in BitBucket, the .jar file without the extra .class files deploys, enables, and works without error. Why is this happening? Please read below for more details.

 

I've developed a BitBucket plugin utilizing pre-receive hook modules. The plugin builds successfully using atlas-package. However, when I deployed the plugin's .jar file to BitBucket Server, the plugin uploaded, but was not enabled. In the BitBucket log, I received a few LinkageErrors, as follows:

2017-08-23 17:23:22,903 ERROR [ThreadPoolAsyncTaskExecutor::Thread 72]  c.a.plugin.osgi.factory.OsgiPlugin Unable to start the plugin container for plugin 'com.test.exampleplugin'
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [bundle://137.0:0/META-INF/spring/plugin-context.xml]; nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) previously initiated loading for a different type with name "org/w3c/dom/Element"
       at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
       at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDefinitions(OsgiBundleXmlApplicationContext.java:170)
       at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDefinitions(OsgiBundleXmlApplicationContext.java:140)
       at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
       at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:613)
       at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$800(AbstractDelegatedExecutionApplicationContext.java:60)
       at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:242)
       at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
       at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:220)
       at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:224)
       at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:177)
       at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:157)
       at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:207)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
       at java.lang.Thread.run(Thread.java:745)
       ... 6 frames trimmed
Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) previously initiated loading for a different type with name "org/w3c/dom/Element"
       at java.lang.ClassLoader.defineClass1(Native Method)
       at com.atlassian.plugin.spring.scanner.extension.AtlassianScannerBeanDefinitionParser.parse(AtlassianScannerBeanDefinitionParser.java:47)
       ... 15 common frames omitted

 

Based on answers from similar questions here, I tried the following:

  • In my dependency tree, I saw that dom4j.jar was a transitive dependency of bitbucket-spi.jar. I added an exclusion to the bitbucket-spi dependency in my pom file
  • When the above did not work, I removed the exclusion I had added. I added a dom4j dependency to the pomfile, and within it I added an exclusion for xml-apis
  • When the above did not work, I added the following to my atlassian-plugin.xml:
    <plugin-info>...<Import-Package>org.w3c.dom.*;resolution:="optional"</Import-Package>

All three of the above generated the following NoClassDefFoundErrors:

2017-08-23 18:48:02,683 ERROR [ThreadPoolAsyncTaskExecutor::Thread 74]  c.a.plugin.osgi.factory.OsgiPlugin Unable to start the plugin container for plugin 'com.test.exampleplugin'
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [bundle://139.0:0/META-INF/spring/plugin-context.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/Element
              at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
              at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDefinitions(OsgiBundleXmlApplicationContext.java:170)
              at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDefinitions(OsgiBundleXmlApplicationContext.java:140)
              at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
              at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:613)
              at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$800(AbstractDelegatedExecutionApplicationContext.java:60)
              at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:242)
              at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
              at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:220)
              at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:224)
              at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:177)
              at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:157)
              at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:207)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.lang.Thread.run(Thread.java:745)
              ... 6 frames trimmed
Caused by: java.lang.NoClassDefFoundError: org/w3c/dom/Element
              at com.atlassian.plugin.spring.scanner.extension.AtlassianScannerBeanDefinitionParser.parse(AtlassianScannerBeanDefinitionParser.java:47)
              ... 15 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.w3c.dom.Element not found by com.test.exampleplugin [139]
              at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
              ... 16 common frames omitted

 

To make this slightly stranger, I have another machine with the SDK installed on it. I brought the same source over to that machine, ran atlas-package, then brought the resulting .jar file back to the first machine, and it deployed successfully, and enabled without error.

 

Unpacking the .jar files shows that the ones which generate errors have several extra directories of .class files for various dependencies which are not present in the .jar which worked successfully. The file which generated the LinkageErrors contained an org/w3c/dom/Element.class file. The file which generated the NoClassDefFoundErrors did not contain this file (but did contain several other Element.class files in other locations). The file which generated no errors contained none of these, and in fact only contained .class files for the source code which it contained. The "target\classes" directories in the project folder from which the .jars were built mirrored this: on one machine, only the class files for the source were present, on the other (error generating machine), there were class files for every dependency, it seemed.

 

My apologies for the length of this post, but I'm looking for the answer as to why packaging and deploying the plugin on one machine generates errors, but packaging on the other and deploying on the first would work fine.

1 answer

This widget could not be displayed.

As mentioned here

https://community.atlassian.com/t5/Jira-Core-questions/LinkageError-when-using-jira-api-and-jira-core-together/qaq-p/614492?utm_campaign=immediate_general_reply&utm_content=topic&utm_medium=email&utm_source=atlcomm


I have the same problem. Either I get the linkageError if I do not exclude "xml-apis" in my <dependency>, or I get the NoClassDefFoundError If I exlude "xml-apis".

If I remove the "Element.class" from my target folder (org.w3c.dom.) without exluding it in the pom.xml in my dependency I get the NoClassDefFoundError too.

Did you find a fix for this?

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Aug 21, 2018 in Bitbucket

Branch Management with Bitbucket

As a project manager, I have discovered that different developers want to bring their previous branching method with them when they join the team. Some developers are used to performing individual wo...

1,337 views 8 11
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you