Problems with class-loading since Jira version 7.4.x

Hello,

we have an application that consists of multiple OSGi bundles (.jar) cooperating between themselves.

For example:

  1. first module is called “services” and contains “DomainDao” class
  2. second module is called “commons-utils” and contains “AbstractDaoImpl” class and “AbstractDao” interface
  3. class from first module extends class from second module: “public class DomainDao extends AbstractDaoImpl

Now, this is something we have used for months and years without any issue - running it against 7.3.6 version without any problem.

However, when I try to deploy the application to Jira 7.5.2, it starts failing on class-loading (log attached). I have consulted this issue with colleagues and they got this issue as well few weeks ago developing completely different application when they extend Jira class that implements another Jira interface. For them also, the issue was not present in Jira 7.3.x but just appeared since Jira 7.4.x.

This is clearly a class-loading bug introduced in some of the >7.3.6 versions. It happens when you have a class (module A) that extends another class from another module (module B) which implements interface from the same module (module B). The module B can be yours or from Jira, it doesn’t matter.

It can be solved by going to the problematic class (module A) and making it implement transitive interface:

  • not working: public class DomainDao extends AbstractDaoImpl
  • working: public class DomainDao extends AbstractDaoImpl implements AbstractDao

So, there is a workaround but it is against the way how Java should be developed and it definitively needs solving.

@community: please, has anyone else stumbled upon the same bug?
@bitvoodoo-atlassian: can you please confirm or disprove that this is an Atlassian bug?

Thank you,
Kind Regards,
Martin


Attached log:

2017-11-07 12:55:06,442 ThreadPoolAsyncTaskExecutor::Thread 25 ERROR admin 775x234x1 1k1q9px 0:0:0:0:0:0:0:1 /rest/plugins/1.0/cz.morosystems.jira.tmobile-pmo-services-key [o.e.g.b.e.i.dependencies.startup.DependencyWaiterApplicationContextExecutor] Unable to create application context for [cz.morosystems.jira.tmobile-pmo-services], unsatisfied dependencies: none
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [cz.morosystems.jira.tm.pmo.services.dao.DomainDao]; nested exception is java.io.FileNotFoundException: class path resource [cz/morosystems/mac/utils/dao/ao/AbstractDao.class] cannot be opened because it does not exist
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:182)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:321)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:261)
    at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:444)
    at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:414)
    at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:362)
    at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:254)
    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.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: class path resource [cz/morosystems/mac/utils/dao/ao/AbstractDao.class] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
    at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:98)
    at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:93)
    at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getInterfaces(ConfigurationClassParser.java:797)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:298)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:232)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:191)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:174)
    ... 15 more

Hi Martin,
I have tried to reproduced this problem and I’ve failed. It seems to work for me with Jira 7.5.2. Here is repository with my attempt: https://bitbucket.org/pbugalski/classloading-test
I guess that I have some different Spring context configuration than you. Can you provide more details so that I can reproduce this problem? (Pull request to my example would be awesome :slight_smile: )
Cheers,
Paweł

I was able to reproduce your problem. It looks like I’ve over complicated my Spring context. With simple context, problem is reproducing.

Hello Paweł,

great to hear that! Fingers crossed with investigation of the problem. :slight_smile: