Ant or Gant?
Join the DZone community and get the full member experience.
Join For FreeYes, this is exactly what I am frequently asked by my clients and many developers. It isn't easy to answer this question. There are several projects using Ant. Should you run away from Ant just because there is a new cool tool out there called Gant? Should you switch to Gant just because you dislike XML? Not at all. Let's take a closer look and see what might make you switch to Gant.
When to choose Gant?
1. Complicated Build Files. If your ant build files are becoming too complicated, and hard to manage, it's time to see if using Gant can help. Let me explain what I mean by complicated build files. If you have too much of conditional logic within your build files, say something similar on the lines shown below in Listing 1:
Code Listing 1:
<if>
<isset property="sqlserver"/>
<then>
<do something here/>
</then>
</if>
<if>
<isset property="oracle"/>
<then>
<do something else here/>
</then>
</if>
<if>
<isset property="derby"/>
<then>
<do something for derby here/>
</then>
</if>
<if>
<isset property="db2"/>
<then>
<do something for db2 here/>
</then>
</if>
Or even something like this where you might be supporting deployment to different application servers based on some property in your build.properties as shown in listing 2.
Code Listing 2:
<if>Things get out of hand when you have conditional logic as shown above in your build scripts. The listings I have are just the skeleton, imagine what happens when we start adding the actual deployment logic for all these application servers. It doesn't matter how you refactor this, it is still going to be very complicated. Trust me, I have written build scripts which were several thousand lines, and refactoring them was not a trivial task.
<isset property="server.jboss4"/>
<then>
<deploy to JBoss 4/>
</then>
<elseif>
<isset property="server.weblogic10"/>
<then>
<deploy to web logic/>
</then>
</elseif>
<elseif>
<isset property="server.glassfish"/>
<then>
<deploy to GlassFish/>
</then>
</elseif>
<elseif>
<isset property="server.someother version"/>
<then>
<deploy to this some other version/>
</then>
</elseif>
</if>
2. Custom Ant Tasks. I myself am guilty of writing many of these. There are many situations which arise in projects where we create custom ant tasks. It is simple once you know how to write one, and than for every complicated task you need to perform, you involuntarily will start writing custom ant tasks.
Anyone writing a custom ant task will:
a. Create a new class that extends Ant’s org.apache.tools.ant.Task class.
b. For each attribute, write a setter method.
c. Write an execute()method that does what you want this task to do.
There isn't anything wrong in doing the above, but imagine each time you want to make a small change, you will have to make changes within your Java source code, compile, test, and re-package.
3. Scripting. You can extend Ant further by not writing custom ant tasks, but by using small snippets of code written in an interpreted language like JRuby, BeanShell, or Groovy. These code snippets can be placed within your build files or in separate text files. If you are using Groovy's Ant task, your build file might look something like this:
Code Listing 3:
<groovy classpathref="build.classpath">
import some.package
import another.package
def fullpath = "${.basedir}/${defaulttargetdir}"
def somefile = new SomeFile(projectName:"${pname}",
buildLabel:"${label}", buildTime:"${new Date()}")
def xml = "${fullpath}/dashboard.xml"
new File(path).write(somefile.generateReport())
ant.xslt(in:path,
out:"${properties.defaulttargetdir}/some.html",
style:"${properties.defaulttargetdir}/lib/report-style.xsl")
</groovy>
Imagine having several lines of XML in your build files which have many of these small snippets of scripts. I myself don't like mixing and matching build files with code snippets. If you have a team where everyone is in the same page, everything works fine. What if a team member has no clue about any of the Scripting languages? He/She will have no clue how to make minor changes when things go badly. If you have all the above or even one of the above three cases, you seriously need to consider using Gant. To quote Aristotle:
For the things we have to learn before we can do them, we learn by doing them."
So, lets see how easy it is to learn Gant and see how things can improve.
This part covers the very basics of Gant. The next part, will dive deeper into Gant by using it with a sample project to build an application, and we will also see how to use it with our CI Server.
What's Gant?
Gant is a build tool that uses both Groovy and Ant. With Gant, you describe your build process using Groovy scripts. Stated simply, Gant allows you to specify the build logic using Groovy instead of XML. The next thing you may ask is " Is Gant a competitor to Ant?". Let me quote from the Gant web site to make thing more clear here :
Whilst 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.
Download and Install Gant.
In order for Gant to work, you should have Groovy installed. You can download and follow the installation instructions for Groovy here.
As I said earlier also, in order to use Gant, you should have knowledge of Groovy as well. If you have never written Groovy code before, there are many interesting books on Groovy like:
You can also read the getting started guide on the Groovy web site, which should give you a good starting point.
Download the latest version of Gant from here. Gant is currently at version 1.4.0. Unzip it to a folder. If you already have your GROOVY_HOME set, that's all you need to use Gant.
Getting Started. Open a console, and type gant. You should see a message as shown below:
meera-subbaraos-macbook-9:~ meerasubbarao$ gant
Cannot open file build.gant
meera-subbaraos-macbook-9:~ meerasubbarao$
You are all set at this point to use Gant in your projects.
Help Information: Open a console, and type gant -h. This will provide you with all the necessary help information you need as shown below:
meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant -h
usage: gant [option]* [target]*
-c,--usecache Whether to cache the generated class and
perform modified checks on the file before re-compilation.
-n,--dry-run Do not actually action any tasks.
-C,--cachedir <cache-file> The directory where to cache generated
classes to.
-D <name>=<value> Define <name> to have value <value>.
Creates a variable named <name> for use in the scripts and a property
named <name> for the Ant tasks.
-L,--lib <path> Add a directory to search for jars and
classes.
-P,--classpath <path> Specify a path to search for jars and
classes.
-T,--targets Print out a list of the possible targets.
-V,--version Print the version number and exit.
-d,--debug Print debug levels of information.
-f,--file <build-file> Use the named build file instead of the
default, build.gant.
-h,--help Print out this message.
-l,--gantlib <library> A directory that contains classes to be used
as extra Gant modules,
-p,--projecthelp Print out a list of the possible targets.
-q,--quiet Do not print out much when executing.
-s,--silent Print out nothing when executing.
-v,--verbose Print lots of extra information.
Create a new file called build.gant at the root of your project.
Did a similarity between Ant and Gant strike you here? Ant build files are usually called build.xml, and they are created as a common practice within the root of your project folder as well.
If you have written or even modified Ant build files, you will know that it contains one project element, which in turn contains a name,the default target and the base directory.
Code Listing 4:
<project name="GantSamples" basedir="." default="compile">
So for example, sayHello target in Ant would look something like this:
<target name="sayHello" description="Saying Hello">
<echo message="Hello Javalobby"/>
</target>
Lets create the sayHello target, and also see how to set it as the default target in Gant as well.
A Gant target has a name and a description:
Code Listing 5:
target ( target-name : target-description ) {
groovy code sequence
}
The above sayHello target in Gant would translate as shown below:
target(sayHello:"Saying hello"){
Ant.echo(message:"Hello Javalobby")
}
Now, open a command window and type gant at the root of the project where the build.gant file exists. You should be able to see a output like:
meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant
Target default does not exist.
Gant is complaining that we haven't set a Default target. Lets see how to do the same:
Default target: Within Ant, you define the default target from within the project element as seen in Listing 4. The default target is the target called if no target is specified from the command line. There however is no project tag within Gant. There are two ways of specifying the default target as shown below:
1. You simply create a target whose name is default.
target ( 'default' , 'The default target.' ) { aTarget ( )
2. or even simply:
setDefaultTarget ( aTarget )
In order to get our sayHello target working, we need to add one of the above scripts to our build.gant file.
Code Listing 6:
setDefaultTarget(sayHello)
or
target ("default": "The default target." ) {
sayHello ( )
}
Complete listing of build.gant:
target(sayHello:"Saying hello"){
Ant.echo(message:"Hello Javalobby")
}
/*
target ("default": "The default target." ) {
sayHello ( )
}
*/
setDefaultTarget(sayHello)
And you should be able to see:
meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant
[echo] Hello Javalobby
meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$
That was easy! If you have build files and it is becoming unmanageable by your team, there is a tool out there which can convert your Ant scripts to Gant scripts as well. I haven't used it, but you can try it here.
In this part of the series, we learned when to move over from Ant to Gant, downloaded and installed Gant, and finally wrote a simple gant build file. In the next part of this series, we will see Gant in Action within a simple Java project.
And as always, keep us posted here if you are encountering any problems getting started with Gant. Stay tuned.
Opinions expressed by DZone contributors are their own.
Comments