As part of the preparations for the recent 1.0.0 release of jclouds, I was tidying up the existing Tweetstore demo application as well as porting it to CloudBees' Tomcat-based RUN@cloud platform. A key part of the test harness for the original versions of Tweetstore that run on the Google App Engine is the neat GoogleDevServer class. Basically, it's a clever wrapper around the KickStart class used under the covers by the GAE SDK tools that allows you to specify the SDK location, address, port and WAR file (or expanded WAR directory) to run. Better still, it can programmatically be shut down cleanly, making it ideal for integration test runs1. For CloudBees, I was thus looking to put together a similar RunAtCloudServer. It proved more challenging than expected...2
Just spawn a container already?Both the maven-gae-plugin and the bees-maven-plugin allow you to spawn a local GAE or RUN@cloud server simulation, of course. These can easily be integrated into your Maven build, for instance as part of your pre-integration-test setup. So why not just stick with that? Well, for some scenarios that can be perfectly sufficient. For Tweetstore, having an inline server that cleanly shuts down allows us to:
- run integration tests alongside unit tests from an IDE without having to remember to start an external process
- debug the application running in the server on demand, without having to mess with remote debuggers or figure out a way to sometimes get the Maven plugins to start in debug mode
- work some conditional magic with the server arguments
The RUN@cloud SDK's version of KickStart is the StaxSdkAppServer3. Figuring out the correct arguments for the launchServer factory method wasn't too hard, so I hooked up a StaxSdkAppServer and kicked off the test. Started like a charm! Then the test finished and...just hung on in there. Over in the trusty debugger4, I could see not one, but two zombie threads still running. The design was based on a "shutdown-by-JVM-kill" scenario, I guess.