RSS feed
<< November 9, 2009 | Home | November 11, 2009 >>

Make your war file executable with the Jetty Console Maven plugin

A while back I made a little Maven plugin that takes a war file and makes it executable. With executable I mean that it embeds a Jetty servlet container. Running java -jar myapp.war will deploy your war with the embedded Jetty instance.

This provides a very convenient distribution method for Java web applications. It lets you distribute your application as a single artifact. Your users are no longer forced to install a big and ugly app server just to run your app.

But if they really want to, the war is still a war file that can be deployed the "normal" way in Tomcat, Glassfish, Weblogic, Websphere or any servlet compliant web server. (You tell me you actually use Websphere? Seriously!?).

With a single distribution in a single file, there's also less chance of your users getting confused about how to get your application running.

Jan Bartel of Jetty fame asked for a link describing this plugin and since I didn't really have any thing useful, here's a blog post:

An example: The Puffin Secrets Webapp

Meet the Puffin Secrets webapp. This very small, yet very useful web application let us listen in on the puffins while they chat about Jetty:


Since puffins are a bit shy, we need to click the button to see what they really think about Jetty:


To make this war file executable, we need to add a bit of plugin configuration to our Maven pom.xml:

<plugin>
<groupId>org.simplericity.jettyconsole</groupId>
<artifactId>jetty-console-maven-plugin</artifactId>
<version>1.23</version>
<executions>
<execution>
<goals>
<goal>createconsole</goal>
</goals>
</execution>
</executions>
</plugin>

After running mvn clean install, we should now have a target directory looking like this:


Notice the -jetty-console.war version of your war file. This war file is now runnable with java -jar (On a Mac it's actually double-clickable!). Running the war will start a little Swing console (unless run on a server):


The flies are there to remind you that you probably have bugs in your code. Still you might want to use a less generic background image. This can be done by adding the following configuration:


<plugin>
<groupId>org.simplericity.jettyconsole</groupId>
<artifactId>jetty-console-maven-plugin</artifactId>
<version>1.23</version>
<executions>
<execution>
<goals>
<goal>createconsole</goal>
</goals>
<configuration>
<backgroundImage>${basedir}/src/main/jettyconsole/puffin.jpg</backgroundImage>
</configuration>
</execution>
</executions>
</plugin>


This gives us a much more puffin-relevant background:


The console is currently pretty simple. It allows the user to select a port and start the application. As a convenience the console will open a browser with the correct URL. This saves the user some seconds. (When demoing a product, seconds matter!)

Command line options

While the graphical console is nice for demoing an application or distributing it to testers, for installation on a server we need some command line interaction. You can see a list of available options by typing java -jar myapp.war --help

Usage: java org.simplericity.jettyconsole.JettyConsoleStarter [--option=value] [--option=value]

Options:
--sslProxied - Running behind an SSL proxy
--port n - Create an HTTP listener on port n (default 8080)
--bindAddress addr - Accept connections only on address addr (default: accept on any address)
--forwarded - Set reverse proxy handling using X-Forwarded-For headers
--contextPath /path - Set context path (default: /)
--headless - Don't open graphical console, even if available
--help - Print this help message
--tmpDir /path - Temporary directory, default is /tmp

Plugins

The core of the Jetty console is intentionally kept as small as possible. Additional functionality can be included by adding plugins to your plugin configuration. You might want to add the log4j plugin:

<configuration>
<backgroundImage>${basedir}/src/main/jettyconsole/puffin.jpg</backgroundImage>
<additionalDependencies>
<additionalDependency>
<artifactId>jetty-console-log4j-plugin</artifactId>
</additionalDependency>

</additionalDependencies>
</configuration>

This should give you an extra option when running --help :

Usage: java org.simplericity.jettyconsole.JettyConsoleStarter [--option=value] [--option=value]

Options:
--sslProxied - Running behind an SSL proxy
--port n - Create an HTTP listener on port n (default 8080)
--bindAddress addr - Accept connections only on address addr (default: accept on any address)
--forwarded - Set reverse proxy handling using X-Forwarded-For headers
--contextPath /path - Set context path (default: /)
--headless - Don't open graphical console, even if available
--help - Print this help message
--tmpDir /path - Temporary directory, default is /tmp
--logConfig file - Read log4j configuration from file

The other plugins currently available are:

ajp: Lets you configure an AJP connector in Jetty
requestlog: Allows you to log requests to an access log for traffic analysis
jsp: Adds JSP support to your application
jettyxml: Allows you to apply arbitrary Jetty XML configurations to your Server or WebAppContext
gzip: Compresses your HTML, CSS and Javascript for bandwidth savings

If the available plugins don't match your needs, it's quite easy to make your own and include it with in <additionalDependencies/>. <additionalDependencies/> can also be used to add normal Maven dependencies, such as a database driver referred to in jetty.xml

Maven repository configuration

Since this plugin is not (yet) in the Maven Central repository, you'll need to add a pluginRepository to your pom.xml:

<pluginRepositories>
<pluginRepository>
<id>kos</id>
<url>http://opensource.kantega.no/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>

<repositories>
<repository>
<id>kos</id>
<url>http://opensource.kantega.no/nexus/content/groups/public/</url>
</repository>
</repositories>

The complete puffin example webapp is available in Subversion here:

http://simplericity.org/svn/simplericity/trunk/jetty-console-example/