» How often do you redeploy your J2EE application?

How often do you redeploy your J2EE application?


Posted on 11 January 2011 - 11:37

The guys at ZeroTurnaround have published an interesting report on the development habits from over 1300 Java developers. One of the questions that really struck me was "how often do you redeploy?"

My answer to this question is "on my development machine, never". I use Jetty which is really easy to embed in a regular application. So all of the projets I work on have this tiny class in their src/run/java directory:

package net.bluxte.project;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.webapp.WebAppContext;

public class StartProject {
    
    public static void main(String[] args) throws Exception {
        Server server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setHost("127.0.0.1");
        connector.setPort(8888);
        connector.setForwarded(true);
        server.addConnector(connector);
        
        WebAppContext context = new WebAppContext("src/main/webapp", "/");
        context.setClassLoader(Thread.currentThread().getContextClassLoader());
        server.setHandler(context);
        
        server.start();
        server.join();
    }
}

This tiny class allows me to start the server with just a single click on Eclipse's "Run" or "Debug" icons in the toolbar, using the project's classpath where everything is already compiled by the IDE. No need to build a war file, no need to attach to a remote JVM for debugging, no need to wait for long package/deploy/restart operations. And of course code hotswap works just like it should and makes debugging a breeze.

Now the answer "on my development machine, never" is incomplete, and should be added "on the integration server, every time a source file changes" since Hudson picks up any changes, does a full build/test cycle and deploys the new version automatically on a test machine.

Complex "enterprisey" frameworks and specifications have made us forget that things can be simple if you think a bit, and that it also often pays to do a bit of "development design" to increase the developer's productivity without resorting to "helper tools" that only add some bloat to the process.

Anonymous's picture

I wrote never too :) My jetty is JTA enhanced by Atomikos http://www.atomikos.com/Main/TransactionsEssentials

Anonymous's picture

Then your app doesn't use any EJBs, distributed transactions, webservices, DB pools etc.

Sylvain's picture

I rarely use container-level resources, if this is what you mean. And when I do, a special development-time Spring configuration allows me to use locally-defined resources to avoid the heavy deployment cost.

Anonymous's picture

If you're using maven, there's a jetty plugin that makes it even it easier. No need for an extra class, just add the plugin to your pom.

Anonymous's picture

But you're still bounded by the limitations of Hotswap. When you're altering your Spring config, adding methods to a class, adding a class, changing a JPA entity, you'll still be reloading (or in your case restarting your web container). Your post is a bit misleading; you don't redeploy when you encounter something Hotswap can't handle, but you restart your Jetty server. Same problem if you ask me :).

Sylvain's picture

Indeed, I restart Jetty a lot. But by having it work directly with the source and classpath tree used by Eclipse, I save a significant amount of time by avoiding the steps of war packaging, copy and expansion by the container.

Also, as I mentioned earlier, I use specific development-time Spring configuration snippets (with imports) that avoid starting heavy subsystems that aren't needed for the parts of the code I'm working on at a given moment. Saves some more startup time, even if of course I sometimes have to load everything.

Anonymous's picture

Well hotswap just got better.
http://wiki.apidesign.org/wiki/Hotswap

While you developing you hardly ever packaging things to a war and deploy. You have your IDE to compile and copying it to the container for you and for me this happens really fast on GF v3.

Anonymous's picture

This doesn't happen if you enable "run with resources from workspace".

Anyway deployment is relativly cheap operation when compared to booting of spring context for mediumsized project. and you still from that.

Try using jrebel with jetty. ;-)

Anonymous's picture

I never deploy neither. And I think I have a better solution than yours because you are messing up with the classloaders! The container and the webapp have the same classloader. And in your Eclipse project you may have some jars required for units tests which get loaded whereas they should not be there in production-like deployment.

What I wrote is an Eclipse plugin which is extending the usual java launcher. In the usual java launch configuration you can configure the classpath. With my plugin, the I use this configured classpath to be the jetty's extra classpath: http://docs.codehaus.org/display/JETTY/Classloading#Classloading-Usingth...

And this works very nicely with IvyDE, contrary to the other launch frameworks like WTP.

I should probably get it open source :p