Pre-installed JCMA prevents app from enabling

Hi everyone,
We noticed that in the latest releases of Jira (e.g. 8.15 or 8.16) an out of date version of the Jira Cloud Migration Assistant app comes pre-installed.

Our apps support this migration, we followed the provided guides and are using the ‘Option 2’ (tracker/buffer).
https://developer.atlassian.com/platform/app-migration/examples/

Everything works as expected with the latest version of the JCMA (1.5.2). The apps will enable and run perfectly fine whether JCMA is present or not.
However, if one does not update the preinstalled JCMA and keep the outdated version (1.4.4) that comes pre-installed enabled, then our apps will fail to enable until JCMA is disabled, uninstalled or updated. The following exception is logged:

2021-04-29 13:39:30,348+0000 ThreadPoolAsyncTaskExecutor::Thread 36 ERROR admin 807x234x1 15f91z2 62.28.44.194 /rest/plugins/1.0/ [c.a.p.osgi.factory.OsgiPlugin] Unable to start the plugin container for plugin 'com.xpandit.plugins.xray'
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xrayCloudMigration' defined in URL [bundle://261.0:0/META-INF/spring/atlassian-plugins-components.xml]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xrayCloudMigrationAccessor' defined in URL [bundle://261.0:0/META-INF/spring/atlassian-plugins-components.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.atlassian.migration.app.tracker.CloudMigrationAccessor': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:866)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:57)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:322)
	at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:287)
	at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xrayCloudMigrationAccessor' defined in URL [bundle://261.0:0/META-INF/spring/atlassian-plugins-components.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.atlassian.migration.app.tracker.CloudMigrationAccessor': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1196)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
	... 19 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.atlassian.migration.app.tracker.CloudMigrationAccessor': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:304)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
	at com.xpandit.raven.cloud.listener.XrayCloudMigrationAccessor.setApplicationContext(Unknown Source)
	at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:120)
	at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:96)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:413)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1761)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
	... 29 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:187)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300)
	... 41 more
Caused by: java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:318)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:261)
	at com.atlassian.migration.app.tracker.CloudMigrationAccessor.<init>(Unknown Source)
	... 3 filtered
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:175)
	... 43 more
Caused by: java.lang.ClassNotFoundException: com.atlassian.migration.app.BaseAppCloudMigrationListener not found by com.atlassian.jira.migration.jira-migration-plugin [94]
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1639)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1414)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1590)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 56 more

Does anyone know if this is an issue with our implementation or whether this is expected?

Thanks

1 Like

Hi @claudio.sousa,

We’ve recently updated the README.me files for the server examples to better reflect best practice with using OSGi with the migration assistants. The buffer example will monitor when changes in the OSGi landscape and re-enable itself as necessary.

Can you compare your code against the updated documentation and make sure you’re using

<DynamicImport-Package>
    com.atlassian.migration.app
</DynamicImport-Package>
<Import-Package>
    !com.atlassian.migration.app,
    org.springframework.osgi.*;resolution:="optional",
    org.eclipse.gemini.blueprint.*;resolution:="optional",
    *
</Import-Package>

Regards,
James.

Hi James,
Thanks for your response.
We reviewed the recent changes in the repository and rechecked our implementation. Nothing seems to be missing.

Then, we decided to try the provided buffer example for ourselves. We built the jar for the example and tested it. It behaves exactly the same way as our app:

  • Enables correctly if there JCMA is disabled/uninstalled or if JCMA is up to date (1.5.2)
  • Will not enable if JCMA 1.4.4 is enabled.

Working with 1.5.2:

Not working with 1.4.4:

The following execption is logged:

2021-05-03 15:15:54,056+0100 http-nio-8080-exec-11 INFO admin 915x6288x1 wfaa3j 0:0:0:0:0:0:0:1 /rest/plugins/1.0/my-cloud-app-key-key [c.a.plugin.util.WaitUntil] Plugins that have yet to be enabled: (1): [my-cloud-app-key], 300 seconds remaining
2021-05-03 15:15:54,195+0100 ThreadPoolAsyncTaskExecutor::Thread 187 ERROR admin 915x6288x1 wfaa3j 0:0:0:0:0:0:0:1 /rest/plugins/1.0/my-cloud-app-key-key [c.a.p.osgi.factory.OsgiPlugin] Unable to start the plugin container for plugin 'my-cloud-app-key'
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cloudMigrationAccessor': Initialization of bean failed; nested exception is java.lang.RuntimeException: Failed to initialise CloudMigrationAccessor
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:866)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:57)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:322)
	at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:287)
	at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: Failed to initialise CloudMigrationAccessor
	at com.vendor.LocalCloudMigrationAccessor.setApplicationContext(LocalCloudMigrationAccessor.java:22)
	at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:120)
	at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:96)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:413)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1761)
	... 15 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.atlassian.migration.app.tracker.CloudMigrationAccessor': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:304)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
	at com.vendor.LocalCloudMigrationAccessor.setApplicationContext(LocalCloudMigrationAccessor.java:20)
	... 20 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:187)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300)
	... 27 more
Caused by: java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:318)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:261)
	at com.atlassian.migration.app.tracker.CloudMigrationAccessor.<init>(CloudMigrationAccessor.java:28)
	... 3 filtered
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:175)
	... 29 more
Caused by: java.lang.ClassNotFoundException: com.atlassian.migration.app.BaseAppCloudMigrationListener not found by com.atlassian.jira.migration.jira-migration-plugin [273]
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1639)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1414)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1590)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 42 more
2021-05-03 15:15:54,198+0100 ThreadPoolAsyncTaskExecutor::Thread 187 ERROR admin 915x6288x1 wfaa3j 0:0:0:0:0:0:0:1 /rest/plugins/1.0/my-cloud-app-key-key [o.e.g.b.e.internal.support.ExtenderConfiguration] Application context refresh failed (NonValidatingOsgiBundleXmlApplicationContext(bundle=com.vendor.plugin-buffer-sample, config=osgibundle:/META-INF/spring/*.xml))
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cloudMigrationAccessor': Initialization of bean failed; nested exception is java.lang.RuntimeException: Failed to initialise CloudMigrationAccessor
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:866)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:57)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:322)
	at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:287)
	at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: Failed to initialise CloudMigrationAccessor
	at com.vendor.LocalCloudMigrationAccessor.setApplicationContext(LocalCloudMigrationAccessor.java:22)
	at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:120)
	at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:96)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:413)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1761)
	... 15 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.atlassian.migration.app.tracker.CloudMigrationAccessor': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:304)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
	at com.vendor.LocalCloudMigrationAccessor.setApplicationContext(LocalCloudMigrationAccessor.java:20)
	... 20 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.atlassian.migration.app.tracker.CloudMigrationAccessor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:187)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300)
	... 27 more
Caused by: java.lang.NoClassDefFoundError: com/atlassian/migration/app/BaseAppCloudMigrationListener
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:318)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:261)
	at com.atlassian.migration.app.tracker.CloudMigrationAccessor.<init>(CloudMigrationAccessor.java:28)
	... 3 filtered
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:175)
	... 29 more
Caused by: java.lang.ClassNotFoundException: com.atlassian.migration.app.BaseAppCloudMigrationListener not found by com.atlassian.jira.migration.jira-migration-plugin [273]
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1639)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1414)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1590)
	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 42 more

Regards,
Claudio

2 Likes

Hi @claudio.sousa,

Thanks for this. I’m updating the buffer-sample to make it handle this case more explicitly, and also getting JCMA updated in Jira releases.

To start, I’ve changed the sample code in a few places

  1. Instead of throwing a RuntimeException, I’m logging a WARN and skipping trying to load CloudMigrationAccessor by testing if BaseAppCloudMigrationListener exists.
    private static final Logger log = LoggerFactory.getLogger(LocalCloudMigrationAccessor.class);

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {

            // check if com.atlassian.migration.app.BaseAppCloudMigrationListener can be created
            // this will throw an exception if the class doesn't exist, and we skip loading the CloudMigrationAccessor
            Class.forName("com.atlassian.migration.app.BaseAppCloudMigrationListener", false, getClass().getClassLoader());
            this.registrar = (CloudMigrationAccessor) applicationContext.getAutowireCapableBeanFactory().
                    createBean(getClass().getClassLoader().loadClass("com.atlassian.migration.app.tracker.CloudMigrationAccessor"), AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);

        } catch (Exception e) {
            log.warn("Failed to initialise CloudMigrationAccessor. Ignoring.");
        }
    }
  1. In MyPluginComponentImpl I check if accessor is null
    @Override
    public void afterPropertiesSet() {
        if (accessor != null) {
            accessor.registerListener(this);
        }
    }

    @Override
    public void destroy() {
        if (accessor != null) {
            accessor.deregisterListener(this);
        }
    }

This way, when JCMA or the buffer-sample is loaded, it will only register itself if everything is available.

Another option, however is not at all recommended, is to use an older version of the -tracker library for now, as that doesn’t have the dependency on BaseAppCloudMigrationListener, but I’d have to dig into the commits to see how far back to go.

The updates to buffer-sample should come through in the next few days.

Regards,
James.

Hi @jrichards ,

Great! Thanks for looking into this.
We aplied these changes and can confirm that it works.

Regards,
Claudio

1 Like

Hi,

As an update I’ve created a public ticket for this

and we’re expecting a release soon to the -tracker library to handle this case.