Plugin dependencies

bamboo
plugin-sdk
dependencies
plugin

#1

I’m trying to develop a bamboo plugin, but I don’t think the question is specific to bamboo.

I want to use the docker-java library (github.com/docker/docker-java). I’ve added this to my dependencies in pom.xml:

<dependency>
	<groupId>com.github.docker-java</groupId>
	<artifactId>docker-java</artifactId>
	<version>3.0.14</version>
	<scope>compile</scope>
</dependency>

and I’ve added this to the Import-Package section:

com.github.dockerjava*;version=3.0.14,

But when I start bamboo with my plugin installed, I always get this error:

[INFO] [talledLocalContainer] com.atlassian.plugin.osgi.container.OsgiContainerException: Cannot start plugin: com.veeasystems.clair_bamboo_plugin
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.osgi.factory.OsgiPlugin.enableInternal(OsgiPlugin.java:418)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.impl.AbstractPlugin.enable(AbstractPlugin.java:286)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.PluginEnabler.actualEnable(PluginEnabler.java:130)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.PluginEnabler.enable(PluginEnabler.java:107)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.DefaultPluginManager.enableDependentPlugins(DefaultPluginManager.java:1212)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.DefaultPluginManager.addPlugins(DefaultPluginManager.java:1188)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.plugin.BambooPluginManager.addPlugins(BambooPluginManager.java:104)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.DefaultPluginManager.earlyStartup(DefaultPluginManager.java:573)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.manager.DefaultPluginManager.init(DefaultPluginManager.java:503)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.container.BambooContainer.init(BambooContainer.java:213)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.container.BambooContainer.initialise(BambooContainer.java:200)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.upgrade.UpgradeLauncher.initialiseBambooContainer(UpgradeLauncher.java:157)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.upgrade.UpgradeLauncher.upgradeAndStartBamboo(UpgradeLauncher.java:91)
[INFO] [talledLocalContainer] 	at com.atlassian.bamboo.upgrade.UpgradeLauncher.contextInitialized(UpgradeLauncher.java:42)
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4852)
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5313)
[INFO] [talledLocalContainer] 	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:974)
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1850)
[INFO] [talledLocalContainer] 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[INFO] [talledLocalContainer] 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[INFO] [talledLocalContainer] 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[INFO] [talledLocalContainer] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[INFO] [talledLocalContainer] 	at java.lang.Thread.run(Thread.java:748)
[INFO] [talledLocalContainer] Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle com.veeasystems.clair_bamboo_plugin [115]: Unable to resolve 115.0: missing requirement [115.0] osgi.wiring.package; (&(osgi.wiring.package=com.github.dockerjava.api)(version>=3.0.14))
[INFO] [talledLocalContainer] 	at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3974)
[INFO] [talledLocalContainer] 	at org.apache.felix.framework.Felix.startBundle(Felix.java:2037)
[INFO] [talledLocalContainer] 	at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
[INFO] [talledLocalContainer] 	at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.osgi.factory.OsgiPlugin.enableInternal(OsgiPlugin.java:399)
[INFO] [talledLocalContainer] 	... 26 more

What am I doing wrong?


#2

You don’t need to add packages of libraries that you bundle with your plugin to Import-Package section.


#3

Okay. But if I remove everything I’ve added to the Import-Package tag, I still get the same error:

[INFO] [talledLocalContainer] Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle com.veeasystems.clair_bamboo_plugin [115]: Unable to resolve 115.0: missing requirement [115.0] osgi.wiring.package; (osgi.wiring.package=com.github.dockerjava.api)

Is there not some way to get maven to package up all the dependencies with the plugin jar file? It feels like there should be - at the moment I’m playing a massive game of “guess which jar file contains the dependency that’s missing” - apparently I’m supposed to be able to figure out for myself that the requirement com.google.common.base comes in a file called guava-19.0.jar.


#4

I can copy docker-java-3.0.14.jar to the plugins folder. But this quickly goes down a seemingly bottomless rabbit hole; run tomcat, spot a missing dependency, copy that to the plugins folder, rinse and repeat. Since tomcat takes several minutes to restart, this is a multi-hour exercise (so far) with no end in sight.


#5

Yeah, that really shouldn’t be necessary.

How are you trying to access the library? From the examples that I see on https://github.com/docker-java/docker-java/wiki you shouldn’t access it as a @Component, but rather the “classic” Java way via static methods.
Then OSGI should not try to wire the component and you should not get these problems.


#6

I’ve added a dependency to the Maven POM (as shown above). Then I’ve used the component by writing the usual java code (import com.github.dockerjava...; DockerClient client = DockerClient.getInstance(...);) - there’s nothing componentised about it. Then I copy the docker-java JAR file into the plugins folder and all hell breaks loose (broadly speaking). If I keep on copying JAR files into the plugins folder each time it fails, I eventually end up with an AbstractMethodError in javax.ws.rs.core.UriBuilder.fromUri, which is apparently because of a version mismatch in jersey somewhere, but I’m at sea here.


#7

Perhaps it doesn’t help that docker-java-3.0.14.jar declares a dependency list which is, shall we say, extensive:

Import-Package: com.fasterxml.jackson.annotation;version="2.6.4",com.fasterxml.jackson.core;version="2.6.4",com.fasterxml.jackson.core.type;version="2.6.4",com.fasterxml.jackson.databind;version="2.6.4",com.fasterxml.jackson.databind.annotation;version="2.6.4",com.fasterxml.jackson.databind.node;version="2.6.4",com.fasterxml.jackson.jaxrs.json;version="2.6.4",com.google.common.base;version="[19.0,20.0)",com.google.common.collect;version="[19.0,20.0)",com.google.common.escape;version="[19.0,20.0)",com.google.common.io;version="[19.0,20.0)",com.google.common.net;version="[19.0,20.0)",com.google.common.util.concurrent;version="[19.0,20.0)",io.netty.bootstrap;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.buffer;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.epoll;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.kqueue;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.nio;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.socket;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.socket.nio;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.channel.unix;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.codec;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.codec.http;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.codec.json;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.logging;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.ssl;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.handler.stream;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.util;version="[4.1.11,4.2.0)";resolution:="optional",io.netty.util.concurrent;version="[4.1.11,4.2.0)";resolution:="optional",javax.ws.rs;version="[2.0.0, 2.1.0)",javax.ws.rs.client;version="[2.0.0, 2.1.0)",javax.ws.rs.container;version="[2.0.0, 2.1.0)",javax.ws.rs.core;version="[2.0.0, 2.1.0)",javax.ws.rs.ext;version="[2.0.0, 2.1.0)",org.apache.commons.codec.binary;version="[1.10,2.0)",org.apache.commons.compress.archivers;version="[1.12,2.0)",org.apache.commons.compress.archivers.tar;version="[1.12,2.0)",org.apache.commons.compress.compressors.gzip;version="[1.12,2.0)",org.apache.commons.io;version="[2.5,3.0)",org.apache.commons.io.filefilter;version="[2.5,3.0)",org.apache.commons.lang;version="[2.6,3.0)",org.apache.commons.lang.builder;version="[2.6,3.0)",org.apache.http;version="[4.4.0, 4.6.0)",org.apache.http.annotation;version="[4.4.0, 4.6.0)",org.apache.http.client.config;version="[4.4.0, 4.6.0)",org.apache.http.config;version="[4.4.0, 4.6.0)",org.apache.http.conn;version="[4.4.0, 4.6.0)",org.apache.http.conn.socket;version="[4.4.0, 4.6.0)",org.apache.http.conn.ssl;version="[4.4.0, 4.6.0)",org.apache.http.impl.conn;version="[4.4.0, 4.6.0)",org.apache.http.impl.io;version="[4.4.0, 4.6.0)",org.apache.http.io;version="[4.4.0, 4.6.0)",org.apache.http.message;version="[4.4.0, 4.6.0)",org.apache.http.protocol;version="[4.4.0, 4.6.0)",org.apache.http.util;version="[4.4.0, 4.6.0)",org.bouncycastle.asn1;version="[1.54,2.0)",org.bouncycastle.asn1.pkcs;version="[1.54,2.0)",org.bouncycastle.cert;version="[1.54,2.0)",org.bouncycastle.cert.jcajce;version="[1.54,2.0)",org.bouncycastle.jce.provider;version="[1.54,2.0)",org.bouncycastle.openssl;version="[1.54,2.0)",org.glassfish.jersey;version="[2.23.1,2.24.0)",org.glassfish.jersey.apache.connector;version="[2.23.1,2.24.0)",org.glassfish.jersey.client;version="[2.23.1,2.24.0)",org.glassfish.jersey.client.spi;version="[2.23.1,2.24.0)",org.newsclub.net.unix;version="[2.0.4,2.1.0)";resolution:="optional",org.slf4j;version="[1.7.0, 1.8.0)"

#8

I’d suggest the following: Do not use the Import-Package statement at all, only use the <dependency> declaration in the pom.xml. Also, don’t copy over any jar files to the plugins folder manually.

Does that work?


#9

I’ve been messing with the POM too long. So I’ve started a fresh plugin project, copied my code into it and added the <dependency> to the POM, then built and run it using atlas-run.

This results in yet another (different) OSGI wiring error:

[INFO] [talledLocalContainer] 2018-11-09 17:10:28,141 ERROR [localhost-startStop-1] [OsgiPlugin] Detected an error (BundleException) enabling the plugin 'com.veeasystems.clair_bamboo' : Unresolved constraint in bundle com.veeasystems.clair_bamboo [115]: Unable to resolve 115.0: missing requirement [115.0] osgi.wiring.package; (osgi.wiring.package=com.google.protobuf).  This error usually occurs when your plugin imports a package from another bundle with a specific version constraint and either the bundle providing that package doesn't meet those version constraints, or there is no bundle available that provides the specified package. For more details on how to fix this, see https://developer.atlassian.com/x/mQAN

I have no idea where this dependency is coming from and I’m starting to lose the enthusiasm to figure it out.


#10

Yeah, I get that. OSGI can do that to you :confused: I’m afraid I’m out of my depth here, sorry. Maybe someone else can help you.


#11

I think I’ve got somewhat further by changing my Import-Package statement in pom.xml from:

            <Import-Package>
              org.springframework.osgi.*;resolution:="optional",
              org.eclipse.gemini.blueprint.*;resolution:="optional",
              *
            </Import-Package>

to

            <Import-Package>
              org.springframework.osgi.*;resolution:="optional",
              org.eclipse.gemini.blueprint.*;resolution:="optional",
              *;resolution="optional"
            </Import-Package>

I now have this error:

[INFO] [talledLocalContainer] 2018-11-19 16:37:17,042 ERROR [localhost-startStop-1] [OsgiPlugin] Detected an error (BundleException) enabling the plugin 'com.veeasystems.clair_bamboo' : Unresolved constraint in bundle com.veeasystems.clair_bamboo [115]: Unable to resolve 115.0: missing requirement [115.0] osgi.wiring.package; (&(osgi.wiring.package=com.atlassian.bamboo.build.test)(resolution=optional)).  This error usually occurs when your plugin imports a package from another bundle with a specific version constraint and either the bundle providing that package doesn't meet those version constraints, or there is no bundle available that provides the specified package. For more details on how to fix this, see https://developer.atlassian.com/x/mQAN

This is apparently (as far as I can tell) because I use the com.atlassian.bamboo.build.test.TestCollectionResult API. The instructions at https://developer.atlassian.com/server/bamboo/test-collection-and-reporting/ don’t say I have to do anything special when using this API. Any pointers?