Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-7311

java.lang.ClassNotFoundException when plugin contains a transactionized Spring component

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: Medium Medium
    • None
    • 2.3, 2.5
    • None

      The error below is thrown when you try to load a plugin containing a component wrapped into a spring transaction proxy via the web-ui.

      The classloader used to load the TransactionProxyFactoryBean doesn't know about the EvaluationManager which will be loaded via the plugin classloader. Therefore the exception will be thrown.

      2006-11-14 12:40:58,602 ERROR [com.atlassian.plugin.DefaultPluginManager] addPlugin There was an error loading the descriptor 'Transactionised Evaluation Service' of plugin 'com.atlassian.confluence.extra.evaluation'. Disabling.
      com.atlassian.spring.container.ComponentNotFoundException: Failed to find component: Error creating bean with name 'evaluationManager' defined in class path resource [x]: Error setting property values; nested exception is org.springframework.beans.PropertyAccessExceptionsException: PropertyAccessExceptionsException (1 errors); nested propertyAccessExceptions are: [org.springframework.beans.MethodInvocationException: Property 'proxyInterfaces' threw exception; nested exception is java.lang.ClassNotFoundException: com.atlassian.confluence.extra.evaluation.EvaluationManager]
      at com.atlassian.spring.container.SpringContainerContext.getComponent(SpringContainerContext.java:106)
      at com.atlassian.spring.container.ContainerManager.getComponent(ContainerManager.java:32)
      at com.atlassian.confluence.plugin.descriptor.SpringComponentModuleDescriptor.enabled(SpringComponentModuleDescriptor.java:117)
      at com.atlassian.plugin.DefaultPluginManager.addPlugin(DefaultPluginManager.java:274)
      at com.atlassian.plugin.DefaultPluginManager.scanForNewPlugins(DefaultPluginManager.java:137)
      at com.atlassian.plugin.DefaultPluginManager.installPlugin(DefaultPluginManager.java:101)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:284)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:155)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:56)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
      at $Proxy3.installPlugin(Unknown Source)

            [CONFSERVER-7311] java.lang.ClassNotFoundException when plugin contains a transactionized Spring component

            Matt Ryall added a comment -

            The Spring plugin module type is deprecated and has been replaced by including a Spring configuration file in your plugin, as documented here:

            The recommended way of creating a transaction or participating in an existing application transaction is to use the SAL TransactionTemplate interface programmatically. This avoids any compatibility problems with different versions of Spring or transaction semantics in different applications.

            It has been this way for at least a few releases now, probably since Confluence 3.0. Sorry for not closing this off sooner.

            Matt Ryall added a comment - The Spring plugin module type is deprecated and has been replaced by including a Spring configuration file in your plugin, as documented here: Plugin Framework: Advanced Configuration with Spring XML Files The recommended way of creating a transaction or participating in an existing application transaction is to use the SAL TransactionTemplate interface programmatically. This avoids any compatibility problems with different versions of Spring or transaction semantics in different applications. It has been this way for at least a few releases now, probably since Confluence 3.0. Sorry for not closing this off sooner.

            I am removing the fix-for version now, because we currently don't have the time to fix this bug during the 3.0 release cycle.

            Per Fragemann [Atlassian] added a comment - I am removing the fix-for version now, because we currently don't have the time to fix this bug during the 3.0 release cycle.

            Pushed back to 3.0 unfortunately.

            Andrew Lynch (Inactive) added a comment - Pushed back to 3.0 unfortunately.

            Matt Ryall added a comment -

            This issue is not yet resolved. OSGi (also called "v2") plugins will be able to provide a complete Spring context for their plugins, so this shouldn't be an issue. However, OSGi plugins can't currently get the Confluence PlatformTransactionManager injected because of the different Spring versions used by Confluence and the plugins subsystem. This is tracked as CONF-13343.

            Once CONF-13343 is resolved, we'll be able to recommend using OSGi plugins to solve this problem. Until then, the best solution in Confluence 2.9 or later is to use Tim's suggestion above:

            • instead of org.springframework.transaction.interceptor.TransactionProxyFactoryBean, use com.atlassian.confluence.spring.transaction.interceptor.TargetClassLoaderTransactionProxyFactoryBean

            In earlier versions of Confluence, you can use Don's suggestions: either programmatically use a TransactionTemplate or programmatically create the dynamic proxy.

            Matt Ryall added a comment - This issue is not yet resolved. OSGi (also called "v2") plugins will be able to provide a complete Spring context for their plugins, so this shouldn't be an issue. However, OSGi plugins can't currently get the Confluence PlatformTransactionManager injected because of the different Spring versions used by Confluence and the plugins subsystem. This is tracked as CONF-13343 . Once CONF-13343 is resolved, we'll be able to recommend using OSGi plugins to solve this problem. Until then, the best solution in Confluence 2.9 or later is to use Tim's suggestion above: instead of org.springframework.transaction.interceptor.TransactionProxyFactoryBean, use com.atlassian.confluence.spring.transaction.interceptor.TargetClassLoaderTransactionProxyFactoryBean In earlier versions of Confluence, you can use Don's suggestions: either programmatically use a TransactionTemplate or programmatically create the dynamic proxy.

            Hi Matt, can you have a look at the status here when you are back?

            Per Fragemann [Atlassian] added a comment - Hi Matt, can you have a look at the status here when you are back?

            As a quick fix for this specific problem, the TargetClassLoaderTransactionProxyFactoryBean class I added in 2.9 should work. However this doesn't handle the more general case of all proxies.

            Tim Moore [Atlassian] added a comment - As a quick fix for this specific problem, the TargetClassLoaderTransactionProxyFactoryBean class I added in 2.9 should work. However this doesn't handle the more general case of all proxies.

            I'm bumping this to 3.0 and 2.9.1 because there's no time to address this before 2.9rc1.

            Perhaps we can come up with a way of addressing this quickly in 2.9.1 and a more general, complete solution for 3.0, perhaps part of the work to use the full power of atlassian-plugins 2.0

            Christopher Owen [Atlassian] added a comment - I'm bumping this to 3.0 and 2.9.1 because there's no time to address this before 2.9rc1. Perhaps we can come up with a way of addressing this quickly in 2.9.1 and a more general, complete solution for 3.0, perhaps part of the work to use the full power of atlassian-plugins 2.0

            The classloading changes we've made in 2.9 haven't solved this problem. I still maintain we need to provide the class property editor with access to the plugin class loader to solve this issue.

            Christopher Owen [Atlassian] added a comment - The classloading changes we've made in 2.9 haven't solved this problem. I still maintain we need to provide the class property editor with access to the plugin class loader to solve this issue.

            This should be fixed in Confluence 2.9. We'll need to confirm once the release is final.

            Jonathan Nolen (Inactive) added a comment - This should be fixed in Confluence 2.9. We'll need to confirm once the release is final.

            Can we get a fix for this already? Having to restart confluence for changes to my plugin is a major hassle.

            Eric Anderson added a comment - Can we get a fix for this already? Having to restart confluence for changes to my plugin is a major hassle.

              matt@atlassian.com Matt Ryall
              jens@atlassian.com jens
              Affected customers:
              13 This affects my team
              Watchers:
              12 Start watching this issue

                Created:
                Updated:
                Resolved: