Developing with Jetty: Where Have You Been All My Life?

Do yourself a favour – check out Jetty6.

It’s been a while since I’ve done any form of webapp development, so I’m a bit rusty. The last place I worked at ran Tomcat servers (quite successfully), so development was naturally done against the same, with the occasional foray into Resin. But both suffered from the problem that fairly regularly, someone would get their dev environment misconfigured and spend some time troubleshooting where it had all gone wrong. It was inevitably something simple and completely unrelated to the NullPointerException or some other runtime exception that had popped up in the logs or in the browser.

With IDEA having Tomcat support built in, when I was starting to test the new webapp I naturally fell back to the old habit of firing that up. And then, no end of of problems:

  • The Windows install of Tomcat omits all the startup scripts because you get a service, and you’d never want anything else, right? The IDEA support requires the scripts, so I grab the tarball instead.
  • Errors on startup. SEVERE: Error filterStart. I know that means an exception in the filters I have configured. I’d like to know what it is. But the only way I’m extracting it is with a breakpoint and startup in debug mode (yes, this was my fault, but a little more helpful error message would be nice).
  • Ok, everything working. Webapp redeploys most of the time, in about 15-20 seconds after making changes. Sometimes it needs a stop/start cycle to pick it up though.
  • Somehow I manage to get a NullPointerException on startup when it was working before. Googling seems to indicate this is an invalid ROOT.xml, as I see a user getting reprimanded for not bothering to do validation on the XML. Sorry, but a NullPointerException is a bug, user error or not. I can’t find the cause, the XML is valid and I’ve deleted IDEA’s cache of the tomcat base to no avail.

The IDEA support for Tomcat is actually quite good, but I just didn’t have time for this. This was with a default configuration!

Luckily, Jetty6 to the rescue. I’ve heard much about it recently and I know they just did a Maven 2 plugin that sounded cool. I wasn’t really aiming to learn another new technology, but thought it was worth a shot since it was on my todo list and I wasn’t getting anywhere. Less than 5 minutes later, the environment is running flawlessly with features I’ve had to fumble around to set up for other containers in the past:

  • web resources read directly from the source tree, so you can edit, save, refresh without any deploying, etc.
  • detects changes on a scheduled interval (I’m using 10 seconds), reloads the webapp if classes/descriptors/libs change. It reloads fast and I haven’t seen it fall over on it yet.
  • Very little setup required.

What setup was required?

First, the normal Maven2 stuff: run the archetype command to generate a skeleton webapp project, start adding web content, and run mvn package to build the WAR. I’d done all this before using Tomcat today. Because of the way I was using Tomcat, I wasn’t using mvn package, but had used mvn idea:idea to generate the appropriate webapp IDEA module and was letting it do all the exploded webapp creation in the Maven layout, so I could continue to use that as is.

To set up Jetty6, I added this to the POM:

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty6-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <contextPath>/</contextPath>
  </configuration>
</plugin>

The rest of the defaults were fine. Then:

mvn jetty6:run

Jetty is now sitting on localhost:8080 with the webapp running, listening for changes.

This is my ideal set up for development, and I don’t see myself going back any time soon. A huge thanks to the Greg and Jan for their work on this. I’m really looking forward to using it some more.

5 responses to “Developing with Jetty: Where Have You Been All My Life?

  1. Samuel Le Berrigaud

    It looks great, and much easier than Tomcat for development purpose…

    I tried it quickly (took really 5mins), the only problem I got now is that my project expect some libraries to be provided by the container (such as the jdbc driver, javamail, activation, and others…) which then have the scope “provided” in the POM…

    It doesn’t seem that the maven jetty plugin add them to the classpath, and I think it should…

    Maybe I’m wrong or I missed something… Cannot ask to get everything working in only 5mins !

    I’ll definitively give it a go, anyway and spend some more time figuring things out…

    Thanks for the tip !

  2. Samuel,

    you could add a profile to your POM defining the additional dependencies with default scope.

    Then run jetty with
    $ mvn -PmyJettyProfile jetty6:run

    Cheers,
    -Ralph.

  3. Hi Brett,

    Nice blog post. I love Jetty too.

    For anyone interested here’s how to do the same thing using the Cargo m2 plugin: http://blogs.codehaus.org/people/vmassol/archives/001307_cargo_v07_and_maven2_plugin_v01.html

    Thanks

  4. Great plugin from Jetty guys, but, do you know how (or if it is possible) can the plugin be aware about changes in configuration files? For example, changes in spring configuration files, sitemesh decorator definitions, *.properties, etc etc

    Thanks in advance!

  5. Brett,
    The Jetty plugin is nice, but we went one step further for WebWork users with QuickStart, which provides automatic Java source code compiling and reloading:

    http://www.opensymphony.com/webwork/wikidocs/QuickStart.html

    And thanks to the IDEA plugin for Maven as inspiration, QuickStart will now read your IDEA .iml files and use that to configure the Jetty server.

Leave a comment