ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Got Project Automation? Got Project Automation?

by Mike Clark
11/10/2004

Editor's Note: In his new book, Pragmatic Project Automation, Mike Clark gives you soup-to-nuts recipes for automating your software project: creating one-step builds with Ant, scheduling continuous builds with CruiseControl, generating software releases at the push of a button, installing and deploying applications with ease, and monitoring builds and running programs via email, RSS, your cell phone, and, yes, even lava lamps. The recipes include working examples that make it easy for beginners to follow along, while more advanced topics teach the old hands something new. In this article, he presents an overview of the benefits that automating your project can bring.

You're on the hook to deliver a software release for a critical demo tomorrow morning. The suits in sales are frothing at the mouth to show off your company's new whiz-bang application to some very important people with deep pockets. Just as you're finding your rhythm behind the keyboard, your boss stops by to remind you that this demo could make or break the project. No pressure!

One-Step Build and Test

It's almost noon before you type in the last line of code for those "must-have" demo features. Your favorite IDE says that your code compiles and passes its unit tests. But will your code work as expected when it's integrated with the rest of the system? To find out, you update your local workspace to get in sync with the files currently in the version control system. Then you run the project's one-step build process:

      
  $ ant

That command compiles all of the source files and runs all of the unit tests using the recipe listed in the following Ant build file:


  <project name="whizbang" default="test" basedir=".">

    <property name="build.prod.dir" location="build/prod"/>
    <property name="build.test.dir" location="build/test"/>
    <property name="src.dir"        location="src"/>
    <property name="test.dir"       location="test"/>
    <property name="vendor.lib.dir" location="vendor/lib"/>

    <path id="project.classpath">
      <pathelement location="${build.prod.dir}" />
      <pathelement location="${build.test.dir}" />
      <fileset dir="${vendor.lib.dir}">
        <include name="*.jar"/>
      </fileset>
    </path>

    <target name="prepare">
      <mkdir dir="${build.prod.dir}"/>
      <mkdir dir="${build.test.dir}"/>
    </target>

    <target name="compile" depends="prepare">
      <javac srcdir="${src.dir}" destdir="${build.prod.dir}">
        <classpath refid="project.classpath" />
      </javac>
    </target>

    <target name="compile-tests" depends="compile">
      <javac srcdir="${test.dir}" destdir="${build.test.dir}">
        <classpath refid="project.classpath" />
      </javac>
    </target>

    <target name="test" depends="compile-tests">
      <junit haltonfailure="true">
        <classpath refid="project.classpath" />
        <formatter type="brief" usefile="false" />
        <batchtest>
          <fileset dir="${build.test.dir}"
            includes="**/*Test.class" />
        </batchtest>
      </junit>
    </target>

  </project>

Related Reading

Pragmatic Project Automation
How to Build, Deploy, and Monitor Java Applications
By Mike Clark

As you're writing code, you frequently hit the convenient Build button in your IDE to make sure everything compiles. You've also become addicted to seeing a happy green bar when all of your JUnit tests pass, so you use the JUnit test runner integrated into your IDE. But not everyone on the team shares your love for this IDE, and you wouldn't want to have to fire up the IDE every time someone wanted to create a build. By using a build file that's externalized from your IDE, everyone on the team can consistently build and test the project in one step. (The project down the hall uses Maven to create one-step builds.)

No surprise to you, the build succeeds and you're once again reminded that you are the world's greatest programmer. Not only does this build process give you confidence in your code, it also gives you confidence that the project can be built outside of your IDE.

Feeling rather chuffed, you check in the files you've changed and duck out for a quick bite to eat. You still have a lot to do to prepare for the demo, and you need to leave early to make the first inning of your son's championship tee-ball game. The clock is ticking ...

Bubble Trouble

On the way back to your cube after lunch, you notice that the project's red lava lamp is boiling. Uh oh! When you left for lunch, the green lamp was happily bubbling. While you were gone, the scheduled build process on your project's dedicated build machine tried to build and test the code currently in the version control repository. But something went terribly wrong.

Running builds continuously on your project is easy because of the fact that you can create a build from the command line in one step. This mean you can easily train a computer to do that for you all day long. Otherwise, you'd have to park a developer in front of a command line to run the build file every time a food pellet appeared. Instead, you have CruiseControl configured to automatically create builds on an interval on your project's dedicated build machine, as directed by the following config.xml file:


  <cruisecontrol>
 
    <project name="whizbang" buildafterfailed="false">

      <bootstrappers>
        <currentbuildstatusbootstrapper
          file="logs/whizbang/currentbuildstatus.txt" />
      </bootstrappers>

      <modificationset quietperiod="30">
        <cvs localworkingcopy="checkout/whizbang" />
      </modificationset>

      <schedule interval="300">
        <ant buildfile="cc-build.xml" />
      </schedule>

      <log dir="logs/whizbang">
        <merge dir="checkout/whizbang/junit-results" />
      </log>
   
      <publishers>

        <currentbuildstatuspublisher
          file="logs/whizbang/currentbuildstatus.txt" />

        <!-- email publisher -->
        <!-- RSS publisher -->
        <!-- lava lamp publisher -->

      </publishers>

    </project>

  </cruisecontrol>

The config.xml file tells CruiseControl to wake up every five minutes and check your project's CVS repository to see if a build is necessary. Only if someone on your team has changed an existing file or added a new file to the version control repository will CruiseControl attempt to create a build. It defers how to create a build for your project to an Ant (or Maven) build file. You have CruiseControl configured to run an Ant build file called cc-build.xml, as follows:


  <project name="cc-build" default="build" basedir="checkout">

    <target name="build">
      <delete dir="whizbang" />
      <cvs command="co whizbang" />
      <ant antfile="build.xml" dir="whizbang" />
    </target>

  </project>

The cc-build.xml file bootstraps the build process by deleting the copy of your project used during the last build and checking out a fresh copy of your project from the CVS repository. Then it automatically runs the same build.xml file that you run from the command line to compile and test the project. After running the build file, CruiseControl publishes the build results to all registered publishers. (The project down the hall that uses Maven also uses CruiseControl, but it's configured to watch for modifications in some other version control system that you're happy not to be using.)

Doing all of this work every five minutes is a tireless job, which is exactly why you're glad CruiseControl does it for you. It seemed like overkill when you originally set it up, but you've learned to appreciate the value of timely feedback. The five-minute schedule just compiles all of the code and runs unit tests as a quick sanity check. You also have CruiseControl configured to run a comprehensive suite of system and performance tests on a less frequent interval. If the five-minute build fails, the problem is no more than five minutes old. This makes it easier for you to find and fix the problem, which saves you precious time. And if changes haven't been committed in the last five minutes, then CruiseControl keeps sleeping.

Hark, the build has failed! It's a good thing CruiseControl lit up the red lava lamp, because you may have overlooked the build failure email in your overflowing email inbox. Anxious to get to the bottom of the problem, you pull up the build status web page and find that in your haste you forgot to check in a new file. This is embarrassing, but at least you can easily fix the build now before problems compound into a nightmare debugging session right before the demo.

After checking in the missing file, you force a quick build on the build machine just to make sure everything is golden. Glancing over your shoulder you see the red lava lamp go dark and the green lamp come back to life. Crisis averted; life is good.

Pages: 1, 2

Next Pagearrow