Thursday, July 15, 2010

Advanced Ant Techniques, Part II

Introduction

This January Ant celebrated its 6th year birthday. In January of 2000, the Ant tool, which was created by James Duncan Davidson to build his Apache project called Tomcat, was moved out of the Tomcat source and into a separate Apache project. Since then it has brought the words "build" and "manageability" closer than ever. Ant gained popularity because of its simplicity, extensibility and cross platform support and within a short span of time has become the build tool of choice for a large number of commercial and open source projects alike.

Although Ant has been extremely successful as an enterprise build management tool, most Ant implementations do not use some of the advanced features provided by the tool. In this article, we'll look at a few advanced techniques that can unleash the true powers of Ant, and turn this mere build tool into an indispensable enterprise asset. Examples are provided where applicable, but lack of detailed code is intentional. It is important to focus on the concepts, not so much on the implementation. Software is a writing. Ideas expressed in software, just like in art, music, plays and other media, can be done in many unique ways. Familiarity with the Ant tool and some experimental spirit is all that you need to turn these techniques into real working code.

Automating tests

One of the tenets of Agile development is "test early, test often". It is about implementing common sense testing strategies that make the overall quality of the software that you ship better. By incorporating frequent testing (preferably automated testing) and frequent build/test/deploy cycles, you will detect bugs earlier. To quote Martin Fowler - the key to successful testing is "test to show an application, or parts of it, doesn't work" as opposed to "test to show it works", which is not as rigorous, and hides the real problems till you deploy and start getting support calls.

Ant's support for standard testing suites such as JUnit, HTTPUnit, Cactus and a host of other testing software lets you integrate testing cycles with the build process and get into the groove of Test Driven Development. Although TDD has been around for a while, I have personally seen a large number of projects that don't leverage this integration. Running tests manually is a wasteful use of a talented developer, and it is error prone due to the human factor. A well written suite of tests should be a part of every build process. Running automated tests is especially useful for typical software development companies that have globally distributed development teams.

If you are in the Ant enthusiasts camp, or simply sitting on the testing fence for a while, here are some strategies worthy of consideration:

  • Extend the boundaries of enterprise build management to include unit testing, regression testing, smoke testing, and finally load testing.
  • Tests run on separate multiple dedicated boxes with simulated production configurations.
  • Use Ant to setup test data, and to capture test results. See Techniques beyond building later in this feature.
  • Tightly integrate build and unit test scripts with SCM hooks so that only the changes that pass the unit test gets checked in.

Continuous automation and continuous integration

Activities involved in a typical SDLC workflow offers several opportunities for automation, and Ant offers unlimited possibilities. Here we focus on integrating with Source Code Management(SCM) systems.

Ant tasks are available to talk to most popular SCM systems, including CVS, Subversion, ClearCase, Continuus/Synergy, Microsoft Visual SourceSafe, Perforce SCM, PVCS, SourceOffSite and StarTeam. With Ant's powerful SCM support, you can hook up parts of the build process to your source control system and perform continuous integration tasks such as check out, check in, baselining etc. Marry that with automated testing, and you can detect bugs as early as the day they got in to the source stream. Once you plumb the verification suite from your build file, you can test after every edit to make sure that nothing breaks. The benefits are substantial. Beyond process maturity and repeatability, a rigorous and portable build process the incorporates elements of continuous integration often results in fewer bugs, higher quality and dollars saved.

If you are not yet on the Agile bandwagon, here are some interesting possibilities to tease you into trying this out:

  • build, unit test, baseline in SCM and promote to integration environment.
  • build, unit test, build dependent projects, perform integration test, baseline in SCM and promote to production.
  • build common blocks, unit test, check in changes, baseline, build consumer apps, perform load test, base-line performance metrics, and promote ??? allows you to compare deltas in performance with every build.

You can even build automated edit analysis scripts that checks for modified source files and submits them for a verified check-in process. Ant project contributors use Ant's own source code analysis tool:

ant -f patch.xml 

to automatically generate a patch file to Ant. With some ingenuous hacking, you can actually make this work for your project too. For the sake of brevity, I am omitting the details, but the patch.xml file distributed with Ant source download should serve as a good starting point. If you still need help, drop me a line.

Technique: Stretching Ant

Ant isn't a silver bullet and there are times when you reach a dead end with its capabilities and you may need to take things into your own hands. For example, your build script may need some authentication information from an internal LDAP or Active Directory server in order to promote code from development to production; or you are required to retrieve a build number from an internal repository for baselining an integration stream in CVS. Such needs often call for functionality that is not available from an out-of-the-box Ant installation.

There are two main approaches to extending Ant: invoke an executable or OS command from within Ant, or write a custom task (i.e., ataskdef.) Let's talk more about the second option: writing custom tasks.

Custom

It helps to know that under the covers, Ant tasks are just Java classes. In theory, any Java class can be cooked into an Ant task simply by extending org.apache.tools.Ant.Task class and implementing an execute() method. Here's where you do the work.

package mytasks; import org.apache.tools.Ant.BuildException; import org.apache.tools.Ant.Task; public class CustomTask extends  Task {     public void execute() throws  BuildException {         // ...     } } 

And then, you simply include it in a build file using the tag to adds the new task definition to the current project.