Automating Application Deployment with Tomcat

I’m asking a bunch of questions here so if you’re expecting answers, look elsewhere. In the past couple years, I’ve waded through a bunch of different ways to configure and build Java web applications. At first, I hardcoded connection strings, settings and message strings in the source code, compiled using Eclipse and copied over the JSP and class files to the web server (lame, I know, but you gotta start somewhere). As the applications I wrote got more complex and as I got smarter, I started using Ant to perform the build and I learned about properties files and web.xml. After unpacking alot of other open source Java applications, I’m now using log4j for logging and error messaging, JNDI for configuration (datasource and application configuration stored in Tomcat’s server.xml), resource bundles for storing internationalized message strings, JUnit for running tests and Ant for cleaning, testing and building my apps into a deployable format (war files).

And that’s where it stops being easy. Deployments suck. We have a pretty small environment (a couple test servers, a couple staging servers, a couple live servers) and deploying changes to those servers is tedious. For example, in my development environment, I like to have log4J append any and all information to the console, which lets me watch the system as it starts up and runs:

log4j.category.com.mycompany=INFO, STDOUT

But once I build the application and deploy it to the live environment, I only want error messages and I want them sent to the SMTPAPPENDER:

log4j.category.com.mycompany=ERROR, SMTPAPPENDER

so I’m stuck editing a text file every time we deploy an application. It’s not that big a of a deal, but I also have applications on each server that need to have the appropriate entries in Tomcat’s server.xml (environment entries, JDBC connections, etc..), sometimes Tomcat needs to be restarted after your deploy the war, applications are deployed to different directories on different machines, sometimes the application being rolled out doesn’t work and you need to roll back to the previous version, how do you keep track of all the live / staging / development servers? The environment I work in is pretty small, so all of this can be done by hand, but it’s tedious, boring and error prone. How do you guys that work in larger environments do it? How do you move the .war files from your staging environment to the live environment? Using Ant? Do you trigger Ant tasks on the live servers that check out source code from CVS and build the apps there? Do you restart Tomcat every time? Do you do one half of your machines at a time and then the next half? You can’t be doing this by hand! Any tips?

5 thoughts on “Automating Application Deployment with Tomcat”

  1. Here are a few suggestions.

    First, fix your build script. Paramaterize everything that can be parametarized into properties.

    Use Ant again backed by properties that you defined, to apply filter sets which “configure” application parameters by doing a search/replace on keys that you define.

    If you need more generation of deployment files, take a look at Xdoclet.

    Use version control on your deployment servers. What does this mean? Well, it means you have your enviroments in some sort of version control system. That lets you perform rollbacks on each enviroment that you need.

    Deployment only gets easier the more often you do it. And i’m not talking about the manual way you are going about. I’m talking about using something like CruiseControl to build and deploy your application often. At least every night at the absolute minimum. Doing this will force you to identify just what areas of your deployment process you need to parametarize. You can also use cruisecontrol to deploy to staging/production servers at the push of a button. Once again, clean reliable builds at any time you want them.

    Its a lot of work upfront, but worth its weight in gold.

    jc

  2. There is a way to do this with properties files and the plain old Properties object. First set up a set of properties files with your config items in them. The files will be something like: base, development, beta and finally live. The trick is to put all the settings into base and then only put the changes in the other files.

    Now create a chain of Properties files, parameterised with the type of environment: ‘development’, ‘live’, etc., and only load files up to that point. (If you use the Properties(Properties p) constructor then p will be the parent of the current property set.)

    The really nice thing about this approach is that you just focus on the config that changes so it’s very easy to follow.

    You can then use your set of Properties to do simple search-and-replace on the log files before launching the app.

  3. I suggest you use Maven.
    In a nutshell, you can deploy to different environment simply doing something like this:

    mvn deploy -Pdevel
    mvn deploy -Ptest
    mvn deploy -Pproduction

    Of course, this “magic” requires that you put some intelligence in your pom.xml file (used by Maven).

    Some love Maven and some hate. The learning curve is steep but the results payoff.
    After you know how to configure Maven, it gets easy! … just like everything in life :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>