I needed to create a small, self-contained web application that could be run from the command-line. I’ve been using Grails a lot lately so I looked into the plugins available. There were two that fit the bill, the Jetty standalone plugin and the Standalone App Runner plugin.

Initially I used the Jetty plugin simply because I found it first. It works but has a significant drawback, Jetty unpacks the entire WAR file before running the application. On the Windows box it was being used on this takes several minutes before the application starts. In addition, once I upgraded the application to Grails 2.0.1, the Jetty plugin broke. So I looked into alternatives.

The Standalone App Runner plugin uses Tomcat 7 as an embedded application server. It bundles your application into a standard WAR file and then builds a jar file that contains embedded Tomcat and your application’s WAR file. Unfortunately, the plugin isn’t working correctly. Your application will start cleanly but the first time a web page is accessed you’ll see this error:

    java.lang.NoClassDefFoundError: org/apache/juli/logging/UserDataHelper

The problem is that the tomcat-embed-logging-juli dependency isn’t present in the embedded Tomcat wrapper. Luckily the fix is easy.

First, intall the Standalone App Runner plugin as usual. Once it’s installed, you’ll need to edit two of the plugins files:

  • ~/.grails/2.0.1/projects//plugins/standalone-1.0/dependencies.groovy
  • ~/.grails/2.0.1/projects//plugins/standalone-1.0/scripts/BuildStandalone.groovy

If you’re not on Unix the tilde (~) is short-hand for your home directory. And, of course, ‘' is whatever project you installed the plugin into.

In the plugin’s ‘dependencies.groovy’ file, add the following block to the end of the file:

    runtime('org.apache.tomcat.embed:tomcat-embed-logging-juli:' + tomcatVersion) {
        transitive = false
    }

This new text comes after the runtime entry for ‘org.eclipse.jdt.core.compiler’. This may not be strictly necessary but I haven’t tested it without adding the runtime dependency.

In the ‘BuildStandalone.groovy’ file you’ll need to make two separate changes:

  1. Add an import line to the end of the imports at the top of the file:

     import org.apache.juli.logging.UserDataHelper
    
  2. Modify the buildJar function slightly around line 84. Add a dependency on ‘UserDataHelper’ by appending it to this line:

     for (clazz in [DeployTask, Engine, JspC, LogFactory, JDTCompilerAdapter]) {
    

Making the line look like this:

	for (clazz in [DeployTask, Engine, JspC, LogFactory, JDTCompilerAdapter, UserDataHelper]) {

That’s it. Now when you create the embedded file using ‘grails build-standalone’ the Grails application will work correctly.