Increasing your productivity by using an embedded container in Maven

The Old Days

If you’ve ever developed a web application in Java, you’ve spent a considerable amount of time configuring your container and your IDE. For some applications, this is a small and reasonable sacrifice: “the cost of doing business.” For more complex applications, it’s a brutal time-sink that requires having every engineer that builds your application go through a training session just to get the application started.

With every project I’ve been assigned to, I’ve often had to spend the first day just configuring my environment so it will function exactly like everyone else’s. Typically the procedure has been:

  1. Download and install essential prerequisites : Java, a version control program (SVN, CVS, P4, etc), ANT, and an IDE.
  2. Download source code
  3. Download tomcat (often a very specific version which is no longer the latest version)
  4. Install tomcat
  5. Configure the server.xml and tomcat-users.xml
  6. Configure some local build properties for someone’s ANT script.
  7. Build the application
  8. Deploy

Isn’t this a huge waste?  In my experience, this is a full day for most developers when put on a project for the first time. Some of the really productive ones can do all these steps in a half day.

The New Procedure with Maven

What if you could eliminate most of this? Maven offers the promise to do so.  Here’s the procedure actual we use here at ISG:

  1. Download and install essential prerequisites : Java, a version control program, Maven, and an IDE.
  2. Download source code
  3. Run mvn compile tomcat:run (for JEE5 projects it’s glassfish:run)

Now you can log into the application.   Maven downloads all of the dependencies, builds the application, downloads a container, configures it based on our pom.xml and and deploys it to an embedded container.

To configure your application to use the embedded container, simply edit your Maven pom.xml and add the plugins below to your build section.

<build>
   <plugins>
      <!-- Embedded Glassfish v3 prelude (glassfish:run) -->
      <plugin>
         <groupId>org.glassfish</groupId>
         <artifactId>maven-glassfish-plugin</artifactId>
         <version>1.0-alpha-4</version>
         <configuration>
            <!-- technically optional, but helpful to declare explicitly. -->
            <!-- I personally put all 3 containers on different ports. -->
            <!-- This allows me to test them simultaneously. -->
            <httpPort>8070</httpPort>   
         </configuration>
      </plugin>
      <!-- Jetty Launcher Plug-in -->
      <plugin>
         <groupId>org.mortbay.jetty</groupId>
         <artifactId>maven-jetty-plugin</artifactId>
         <configuration>
            <contextPath>${project.artifactId}</contextPath>
            <!-- This parameter will auto-deploy modified classes -->
            <scanIntervalSeconds>3</scanIntervalSeconds>
            <connectors>
               <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                  <port>8090</port>
                  <maxIdleTime>60000</maxIdleTime>
               </connector>
            </connectors>
         </configuration>
      </plugin>
      <!-- embedded tomcat (tomcat:run) -->
      <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>tomcat-maven-plugin</artifactId>
      </plugin>
   </plugins>
</build>

Now your application can run in Tomcat, Jetty, or Glassfish without any configuration on the user’s part.

Try it yourself:

I recently had to learn how to use Spring WebFlow. Fortunately, their booking sample application (SVN URL) has been configured to build with Maven. I added the snippet above to their POM and was running and modifying their application less than 15 minutes after downloading their sample. All I had to do was paste in the lines of code above and execute one command via command-line (mvn compile jetty:run).

Real-time Editing of Static Resources

Not only can your users launch the application without installing a container, but they can edit most of the application and view the results in real-time. All three containers will automatically publish static resources, such as JSP, CSS, or HTML files to the running application so that the files are instantly viewable. For example, a graphic designer could edit a CSS file, using Dreamweaver, Notepad, or the tool of their choice, and see the results in real-time, in your dynamic JEE application.

Real-time Publishing of Java Code

Jetty supports publishing of Java code automatically. Now you can see your Java code automatically redeployed to the container, on edit. This eliminates the need for contributors to configure an IDE to publish changes to the underlying Java code and view them in the container. While Glassfish doesn’t have auto-publishing support like Jetty, it will do a full redeploy if the user hits enter in the terminal window, which is almost as convenient. Glassfish is also incredibly speedy.

Development Server Atrophy

In the old days, every team had a development server they’d use to deploy their application to after making edits on their machine. Often the developer would code on a local server install and deploy the to the development server when demoing their work-in-progress or collaborating with another contributor.

As soon as we discovered these plugins, we started using our development server less and less. Eventually the company repurposed our development server. When I want another person to view an application’s progress before it hits our staging server, I can have him or her simply type “mvn jetty:run” and start using the application locally.

Conclusion

Maven is not only a powerful tool for building an application and handling its dependencies, but it can even run the application for you. This greatly lowers the barrier to contribution on a Java project as it allows people who aren’t as familiar with IDE’s like, graphic designers, business analysts, and programmers who don’t usually work in Java, to modify files on their local machines and see the results, in real-time, in a dynamic web application. It’s also very handy for demo-ing applications as the app can be setup on new machines very quickly.

Further Reading

Here’s links to the plugins I used:
The embedded Tomcat Plugin
Kohsuke Kawaguchi’s post on embedded glassfish
The Jetty Plugin