I’m writing a plugin for Confluence and trying to use Spring WebFlux’s WebClient but the plugin will not load into Confluence because of classloader problems. I’m using Spring Java Config if that makes any difference.
In my pom.xml I have:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.3.32</version>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-http</artifactId>
<version>1.1.18</version>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-core</artifactId>
<version>1.1.18</version>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
<version>1.0.4</version>
</dependency>
These JARs get included into my plugin when built, but when Confluence loads the plugin I get the errors:
[INFO] [talledLocalContainer] 15:30:30,854 ERROR [ThreadPoolAsyncTaskExecutor::Thread 11] [osgi.factory.OsgiPlugin] onPluginContainerFailed Unable to start the plugin container for plugin 'com.myapp'
[INFO] [talledLocalContainer] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webClient' defined in com.myapp.SpringConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.reactive.function.client.WebClient]: Factory method 'webClient' threw exception; nested exception is java.lang.NoClassDefFoundError: org/reactivestreams/Publisher
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:649)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:477)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
[INFO] [talledLocalContainer] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:929)
[INFO] [talledLocalContainer] at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:57)
[INFO] [talledLocalContainer] at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:322)
[INFO] [talledLocalContainer] at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
[INFO] [talledLocalContainer] at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:287)
[INFO] [talledLocalContainer] at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
[INFO] [talledLocalContainer] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
[INFO] [talledLocalContainer] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
[INFO] [talledLocalContainer] at java.base/java.lang.Thread.run(Thread.java:1583)
[INFO] [talledLocalContainer] Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.reactive.function.client.WebClient]: Factory method 'webClient' threw exception; nested exception is java.lang.NoClassDefFoundError: org/reactivestreams/Publisher
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644)
[INFO] [talledLocalContainer] ... 19 more
[INFO] [talledLocalContainer] Caused by: java.lang.NoClassDefFoundError: org/reactivestreams/Publisher
[INFO] [talledLocalContainer] at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.initConnector(DefaultWebClientBuilder.java:289)
[INFO] [talledLocalContainer] at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.build(DefaultWebClientBuilder.java:266)
[INFO] [talledLocalContainer] at org.springframework.web.reactive.function.client.WebClient.create(WebClient.java:154)
[INFO] [talledLocalContainer] at com.myapp.SpringConfig.webClient(SpringConfig.java:45)
[INFO] [talledLocalContainer] at com.myapp.SpringConfig$$EnhancerBySpringCGLIB$$e0c54048.CGLIB$webClient$5(<generated>)
[INFO] [talledLocalContainer] at com.myapp.SpringConfig$$EnhancerBySpringCGLIB$$e0c54048$$FastClassBySpringCGLIB$$7475d418.invoke(<generated>)
[INFO] [talledLocalContainer] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
[INFO] [talledLocalContainer] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
[INFO] [talledLocalContainer] at com.myapp.SpringConfig$$EnhancerBySpringCGLIB$$e0c54048.webClient(<generated>)
[INFO] [talledLocalContainer] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
[INFO] [talledLocalContainer] at java.base/java.lang.reflect.Method.invoke(Method.java:580)
[INFO] [talledLocalContainer] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
[INFO] [talledLocalContainer] ... 20 more
[INFO] [talledLocalContainer] Caused by: java.lang.ClassNotFoundException: org.reactivestreams.Publisher not found by com.atlassian.platform.dependencies.platform-spring-bundle [7]
[INFO] [talledLocalContainer] at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1591)
[INFO] [talledLocalContainer] at org.apache.felix.framework.BundleWiringImpl.access$300(BundleWiringImpl.java:79)
[INFO] [talledLocalContainer] at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1976)
[INFO] [talledLocalContainer] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
[INFO] [talledLocalContainer] ... 32 more
The line org.reactivestreams.Publisher not found by com.atlassian.platform.dependencies.platform-spring-bundle [7]
suggests OSGi is trying to load the reactive-streams dependency from one of the built-in bundles, but (a) it doesn’t exist and (b) I’m trying to import it from my own bundle.
If I add org.reactivestreams
to the <Import-Package>
element, I get an error that it can’t be found. The JAR is definitely bundled into my plugin. Why can’t it be found?