This post chronicles some of the trials and tribulations that I had to go through to get Spring Boot to run with AWS libraries included.
- Added the AWS SDK to the pom. Got a NoSuchMethodError on some http connectivity method. Turns out that the SDK requires Apache HttpComponents v.4.5.3. whereas Spring Boot bundles within it an older version, perhaps even of HttpClient.
- Added the HttpComponents to the pom. Now I got an error that:
LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
Searched for a solution and found that I could just proceed by “excluding” one of them explicitly from the pom. That worked, albeit you get a warning in Eclipse about overriding the managed version.
- Now I was getting an error regarding NoSuchMethodError on some fasterxml Jackson classes. Sure enough, there was a version incompatibility between two versions of Jackson that were included. I was about to include one explicitly in the pom but then I saw that there are multiple artifact IDs for Jackson libs (one for core, another for Joda).
- After trying to match spring library versions in vain, I resorted to including the BOM of the spring framework to get a consistent set of libraries. This fixed the incompatibilities but now some other spring boot test class was not found.
- After thrashing around trying to understand why it is not found even though it is clearly included, I decided to look inside the jar in the maven local repository. To my surprise, the class was actually not there. Apparently, a couple of spring boot test classes (SpringApplicationConfiguration and IntegrationTest) were Deprecated and were not even included in the jar anymore! Switching to the replacement version got me past that.
- Next, I ran into an error where some logging class was found twice on the classpath. I thought, well, this is another case of including a dependency twice. But it turns out that it is a bug in the JDK! I upgraded to JDK build 1.8.0_152 and that fixed it.
- Next, I ran into a ClasNotFoundException for this class:
org.springframework.context.ApplicationContextInitializer
This was another weird one. Google suggested that there was an incompatibility between the buildpack and Spring Boot 1.4! I had thereafter to start the app by explicitly specifying a build pack on the command line as such:
cf push -b https://github.com/cloudfoundry/java-buildpack.git#v3.7
- After all of this, I was still getting errors starting the app. At this point I thought there must be a better way to do things. A quick search turned up the Spring AWS Cloud which provides a much better starting point!
- After going through another couple of build issues I was finally at the point where the app starts but it fails at the point where it needed the AWS credentials. I made a few mistakes before I got it right:
- Added them to manifest.yaml but got an “not valid identifier” from bash since the property names contain ‘.’
- Following this example, I added an aws-config file that looks somewhat like this but it did not seem to be picked up even after adding a corresponding resource annotation and loading the file explicitly via the classpath.
- Now, I added them to application.properties in the format specified here and they seemed to be picked up, but I started getting an AmazonCloudFormationException complaining that the signature did not match.
- After checking and re-checking the validity of the access key and the secret key they were correct so I had to scratch my head further.
- It turns out that since my app was running in Cloud Foundry in region us-west-2 the AWS SDK was attempting to connect to that region by default. However, my account was actually in us-west-1.
- Configuring a static region got me past this but then I ran into this issue and luckily adding the two lines:
cloud.aws.stack.auto = false cloud.aws.credentials.instanceProfile = false
to my application.properties finally got my app to start!
Now on to actually write some code!