The code depends on Restlet, Guice, Rocoto, Guava, and (minimally) SLF4J. I've included commented-out code that uses the Restlet-Guice extension, which is in incubator status in the Restlet codebase.
The Main class is a GuiceServletContextListener and it has a main method. When you run com.example.server.Main from the command line, the GuiceServletContextListener methods are ignored. When you deploy a WAR that contains the associated web.xml file, the main routine is never called. You can inject the current DeploymentMode into your classes if you want to change behavior depending whether you're running standalone or in Elastic Beanstalk (i.e., as a servlet).
The MainComponent class is where your Restlet component logic goes. Its lifecycle is managed by the MainService class, which is where you can manage other services with lifecycles. (If you use JClouds BlobStores, for example, you can ensure that a singleton BlobStoreContext is closed when the MainService is stopped. Another example: a LifecycleService for the Hazelcast data grid) There is some trickiness to handling shutdown in various cases; make sure you nest try-finally clauses so that every one of your services gets a chance to shut down even if the previous shutdown attempt throws an exception or error.
The MainServletModule and MainServlet classes deal with the details of embedding the component in a servlet (which is necessary in order to use Elastic Beanstalk).
AwsCredentialsModule is an example of how you can inject AWS credentials from either of two sources: system properties defined on the command line (or via Ant invocation) and system properties defined by an Elastic Beanstalk configuration.
The flow of control when running standalone is that the main routine creates an instance of Main with the STANDALONE deployment mode, creates the injector, gets the singleton MainService, and starts it, which causes (in a different thread), the MainComponent to be started.
The flow of control when running as a servlet is that a default instance of Main is created (due to the web.xml directive) and gets the SERVLET deployment mode. Its contextInitialized call creates the injector, which injects the MainService and starts it, causing (in a different thread), the MainComponent to be started.
Files:
- web.xml - web application descriptor
- Main - has main() routine for standalone; is context listener for servlet mode
- MainComponent - the Restlet component we want to be able to deploy in both modes
- MainService - manages lifecycle of MainComponent and (optionally) other services
- MainServletModule - included in module list in Main; configures Restlet-Servlet bridge
- MainServlet - injects MainComponent and returns it as the component it wraps
- DeploymentMode - enum with two values: STANDALONE and SERVLET
- AwsCredentialsModule - example of passing AWS credentials for binding with @Named