Cannot create instance of AWS class in bamboo plugin
Asked by Alistair Mackay:

Hi,

I'm trying to develop a plugin for Bamboo 6.7.1 that utilises the AWS SDK.

<br />

I have this in my project POM.

```
 <dependency> 
    <groupId>com.amazonaws</groupId> 
     <artifactId>aws-java-sdk</artifactId> 
      <version>1.4.7</version> 
      <exclusions> 
          <exclusion> 
             <groupId>commons-logging</groupId> 
             <artifactId>commons-logging</artifactId> 
          </exclusion> 
          <exclusion> 
           <groupId>stax</groupId> 
           <artifactId>stax-api</artifactId> 
          </exclusion> 
       </exclusions> 
       <scope>provided</scope> 
   </dependency>
```

...which seems to agree with other code I've seen using AWS SDK - and that the AWS libraries within Bamboo 6.7.1 are using AWK SDK 1.4.7

All goes well until I try to use the STS Assume Role call

```
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;

...

AWSSecurityTokenServiceClient sts = new AWSSecurityTokenServiceClient(buildServerCredentials);

// The following throws exception on plugin load if present:
AssumeRoleRequest req = new AssumeRoleRequest();
```

```
[INFO] [talledLocalContainer] 2019-05-20 16:06:48,895 ERROR [QuickReload - Plugin Installer] 
[OsgiPlugin] Detected an error (BundleException) enabling the plugin 'com.reedexpo.cloudformation.cloudFormation-tests' : 
Unresolved constraint in bundle com.reedexpo.cloudformation.cloudFormation-tests [123]: Unable to resolve 123.0: 
missing requirement [123.0] osgi.wiring.package; (osgi.wiring.package=com.reedexpo.cloudformation.api) 
[caused by: Unable to resolve 122.0: missing requirement [122.0] osgi.wiring.package; (osgi.wiring.package=com.amazonaws.services.securitytoken)]. 
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
```

Stuck :-(


Answers:
author: Henrik Opel _Utoolity_
body: Hi Alistair,

Those OSGi wiring errors are notoriously tricky to analyze, but your first steps should be to verify that the missing package is:

* ... actually exported by Bamboo - see [Using the OSGi Browser](https://developer.atlassian.com/server/framework/atlassian-sdk/using-the-osgi-browser/) for details.
* ... actually imported by your app - you can use the OSGi Browser mentioned above for that as well, but also directly look into the Import-Package declarations in the "/META-INF/MANIFEST.MF" file generated and included with your apps jar file.

That being said, and given that the AWS SDK bundled with Bamboo is rather outdated, we use an alternative approach in our AWS related apps - explicitly *exclude* the AWS SDK from your main Bamboo API dependency declaration, and then add your own dependencies for the respective [SDK Maven modules](https://github.com/aws/aws-sdk-java#using-the-sdk-maven-modules) you want to use in your POM *with scope "compile".*

While this will result in a bigger jar file, you'll end up with much more control over the SDK features available to your app (i.e. you can update the AWS SDK version as needed), and also less potential for OSGi conflicts (you might still run into some inverse ones that you need to exclude from your compile scope declarations in turn, e.g. the 'commons-logging' one, but I can't say for sure what is needed against Bamboo 6.7.1).

PS: Depending on what you are trying to achieve, you might want to take a look at our (commercial) offerings [Identity Federation for AWS](https://marketplace.atlassian.com/apps/1212482/identity-federation-for-aws-bamboo?hosting=server&tab=overview) (SSO and temporary AWS credentials for reuse in e.g. Bash or PowerShell script tasks) and [Tasks for AWS](https://marketplace.atlassian.com/apps/1211585/tasks-for-aws-bamboo?hosting=server&tab=overview) (a large collection of Tasks covering a wide range of AWS services, including CloudFormation).  
**Disclaimer**: I'm a Co-Founder of these app's vendor Utoolity!

comments: author: Alistair.Mackay
body: Hi Henrik,  

Thanks for the reply! I'll look into this tomorrow.

Would you be willing to share the relevant POM declarations to do what you are describing above? I'm not really a java developer, so how all the dependencies work is currently a little mysterious! It makes sense to me to be able to use the latest SDKs.


author: Henrik Opel _Utoolity_
body: The relevant POM snippets should be roughly like blow (going with AWS SDK Maven modules "aws-java-sdk-core" and "aws-java-sdk-sts" only here - you'll want to add more as needed, e.g. "aws-java-sdk-cloudformation"):

```
<properties>
  <!-- ... snipped unrelated property declarations ... -->
  <bamboo.version>6.7.1</bamboo.version>
  <!-- Central switch for AWS SDK version -->
  <aws.sdk.version>1.11.551</aws.sdk.version>
  <!-- ... snipped unrelated property declarations ... -->
</properties>

<dependencies>
  <!-- ... snipped unrelated dependency declarations ... -->
  <dependency>
    <groupId>com.atlassian.bamboo</groupId>
    <artifactId>atlassian-bamboo-api</artifactId>
    <version>${bamboo.version}</version>
    <scope>provided</scope>
    <exclusions>
      <!-- Ensure no transitive dependency on the AWS SDK from Bamboo -->
      <exclusion>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <!-- You'll always want the core SDK Maven module -->
 ?<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-core</artifactId>
    <version>${aws.sdk.version}</version>
   ?<scope>compile</scope>
    <exclusions>
      <exclusion>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
 ?<!-- Add service specific SDK Maven modules as needed -->
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-sts</artifactId>
    <version>${aws.sdk.version}</version>
   ?<scope>compile</scope>
    <exclusions>
      <exclusion>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <!-- ... snipped unrelated dependency declarations ... -->
</dependencies>
```

Note: I'm not 100% sure at the moment if we still need the additional part below, or if it is just a safeguard against accidental Import-Package declarations deduced by the bnd-tool (I assume the latter), but just in case you still find AWS related Import-Package statements in your MANIFEST.MF, you can explicitly remove them in the maven-bamboo-plugin declaration configuration section (the "!com.amazonaws\*," entry):

```
<build>
  <plugins>
    <plugin>
      <groupId>com.atlassian.maven.plugins</groupId>
      <artifactId>maven-bamboo-plugin</artifactId>
     ?<!-- Snippe unrelated stuff -->
      <configuration>
        <!-- Snippe unrelated stuff -->
        <instructions>
          <Import-Package>
            <!-- Explicitly forbid AWS related imports -->
            !com.amazonaws*,
            *;
          </Import-Package>
        </instructions>
      </configuration>
    </plugin>
  <plugins>
</build>
```

Hope this helps, but as ususal, ymmv, i.e. not sure if this covers all potential conflicts with a Bamboo 6.7.1 compile target.


author: Alistair.Mackay
body: Hi Henrik,  

Once again, thanks!

I have tried the above...

* The plugin JAR does now contain all the aws dependencies
* There's no mention of aws in the MANIFEST.MF Import-Package statement, or the OSGI browser's import-package list
* I note also that the integration test JAR shows a classpath in the OSGI browser pointing at JARs with META-INF, but the main plugin itself has no classpath. Either way, the test JAR also refuses to load - presumably because it depends on the main plugin.

... still blows up!

Is it trying to tell me now that something that was pulled in by the AWS SDK is conflicting with something provided by Bamboo 6.7.1 and thus needs to be found and added to the exclusions list, or forbidden in the Import-Package?


author: Henrik Opel _Utoolity_
body: > Is it trying to tell me now that something that was pulled in by the AWS SDK is conflicting with something provided by Bamboo 6.7.1 and thus needs to be found and added to the exclusions list, or forbidden in the Import-Package?

Possibly/likely, but could also be an unrelated new conflict that was previously masked by the AWS one - welcome to the fun parts of OSGi! (sorry, sarcasm ;)
> ... still blows up!

With unchanged error messages/stack traces in the log? I would hope that they are slightly different, with some pointers to the offending classes now.

We should move this discussion to a new question (with full error log/stack trace) in the [Atlassian Developer Community](https://community.developer.atlassian.com/), which is a separate forum to this user focused one - it offers a (slightly) better editor for code/log formatting, and increases your chances of other developers chiming in.

If you leave a link to the new question here, I'll take another look, though I'll be on vacation starting this weekend and can not make any mid term promises.


author: Alistair Mackay
body: Hi Henrik  

New topic created at <https://community.developer.atlassian.com/t/cannot-create-instance-of-aws-class-in-bamboo-plugin/29437> with complete POM and stack trace from bamboo log.

Although I'm developing on a Windows box, I have also asserted the behaviour is the same running it in a linux container.

My background is C++ then .NET - never really dived into java thus far. Oh well start at the deep end, why not!


Tags: bamboo-app

bamboo-development

developer