If you've ever wished for the command of a programming language to drive your build process, then you need to know about Gant. In this article Klaus P. Berg introduces this smart combination of Groovy and Ant and shows you why some Java developers are choosing it as a more expressive alternative for describing complex build logic.
Apache Ant is a popular open source tool for automating build tasks. Like Maven, Ant is a de facto standard for creating platform-independent builds of Java applications. Besides providing the typical
junit tasks, Ant offers great support for file and directory manipulation. Despite all this power, Ant buildfiles are written in XML, which limits your options for task automation to a given set of XML tags. Although it is possible to use extensions like Ant-Contrib or handwritten Ant tasks to enrich this set, writing Ant buildfiles is an awkward job at best.
In this article, I introduce Gant, a new breed of build tool built on the familiar foundation of Ant. Rather than using XML, Gant lets you describe your build process using Groovy scripts. Using a Java-runtime-based programming language to describe automated build tasks gives you many of the same advantages Martin Fowler lists for Rake, a build language based on Ruby. Gant essentially lets you access the full power of Groovy (and Java) any time you need it, without having to drop out of your build description language to do interesting things. For instance, you can easily use control structures to express build logic, and you can even weave Java code into your build script. Using Ant (and thus XML) means switching over to custom Ant tasks or third-party libraries to perform many of the tasks that make your build worthwhile.
Another advantage to using Gant is the opportunity to practice writing Groovy scripts. As you'll learn in this article, Groovy has a steep learning curve for Java developers -- meaning that we can actually pick it up quite quickly. You'll get your chance to see some simple Groovy scripts in this article, as I walk through the steps involved in migrating an Ant build to Gant. You'll also learn why Gant is becoming a popular alternative for Java developers who need the descriptive power of a programming language to describe complex build tasks.
Quick overview of Ant
While professional IDEs have built-in support to compile, run, and debug your applications, complex software projects require more. In Java enterprise development, especially, you are faced with managing all the intricacies of the application lifecycle -- namely building, testing, deploying, and maintaining -- potentially across multiple platforms, over long periods of time, and/or in a continuous integration environment. Thus, an automated build utility like
make, Maven, or Ant (or, as you'll see, Gant) is a practical requirement for most professional application development.
Look into the heart of Ant's automation capabilities and you will find an XML-based buildfile. It contains several XML tags (or tasks) that will make up your project. The basics of Ant have been covered elsewhere on JavaWorld, so I won't go into them here. It is important that you have the following conceptual architecture of Ant in mind, however, as it carries over to Gant:
- Project: Each Ant buildfile contains one project. The
projectelement can give your build activities a name and a description, and may define the default target and the base directory from which all path calculations will be done. Usually, one project corresponds to one build file, although it is possible to access elements of other projects.
- Target: A target is a set of Ant tasks to be executed. They may depend on other targets, but note that Ant's
dependsattribute only specifies the order in which targets should be executed. It does not affect whether the target that specifies the dependency is executed, in the case that the dependent target does not (need to) run. Typical targets are
jar. A target is only a container or a wrapper for tasks, which do the real work.
- Task: A task is a piece of code that can be executed. It can have multiple attributes or command arguments. Tasks have identifying names that must be unique inside one buildfile. Using Ant's task plug-in mechanism, you can write your own Java tasks or use third-party tasks out of the box.
- Properties: A project usually has a set of properties that are made up of key/value pairs. They might be set in the buildfile by the
propertytask, or outside Ant in a separate property file. Note that once a property has been set, its value cannot be changed; think of it as similar to the
final String constantconstruct in Java.
Ant is a command-line tool, so you will start your build by calling the Ant interpreter and specifying a buildfile (or using the default build.xml). Optionally you can address specific targets or create properties using Ant's command-line parameters.
Meet Gant: Ant's Groovy new cousin
A Groovy-based build system that uses Ant tasks, but no XML. That means Gant makes use of Groovy instead of XML to specify the build logic. A Gant build specification is a Groovy script and so can bring all the power of Groovy to bear directly, something impossible with Ant scripts. While it might be seen as a competitor to Ant, Gant uses Ant tasks for many of the actions, so Gant is really an alternative way of doing builds using Ant, but using a programming language rather than XML to specify the build rules.
Poke around in the wide-open Internet and you will soon find the assertion that Gant is what Ant was meant to be like. Much as I appreciate Gant, I stop short of sharing this opinion. Rather, I would say that Gant is just a different way of doing Ant -- with the keyword being just. I first encountered Gant when I wrote a midsize GWT application. I started out doing all the necessary preparation, compilation, copying, and other build tasks using Ant and Ant-Contrib. But as my build script grew more complicated, I found the Ant-Contrib control structures and property regex processing cumbersome.
After reading a recommendation for Gant in Groovy in Action, I decided to try programming with the best of both worlds: Groovy + Ant = Gant. I liked the result so much that I relied on Groovy and Gant from the start for my next project.
The Groovy in Gant
|Gant and Grails|
This introduction to Gant would not be complete without mentioning that Gant is used as the build system for Grails. Grails is an open source Web application framework that leverages the Groovy language and complements Java Web development. It aims to bring the "coding by convention" paradigm to Groovy, and is inspired by Ruby on Rails. You can use Grails as a standalone development environment that hides all configuration details, or to integrate your Java business logic. See the Resources section to learn more about Grails.
While much of Gant will be familiar to users of Ant, you do need to know some Groovy syntax to use it. Groovy is an object-oriented programming and scripting language for the Java platform. Being a dynamic language, Groovy has features like those of Perl, Ruby, and Python. But Groovy sources are automatically compiled to Java bytecode that works seamlessly with your own Java code or third-party libraries. With the Groovy compiler, you can also produce bytecode for other Java projects. The integration between Groovy and Java code is thorough and smooth. As a result, it has often been said that Groovy has a steep learning curve for Java developers, meaning that we can learn it very quickly.
In Gant, Groovy is tightly integrated with Ant by way of AntBuilder.