Ant
Ant is a Java-based build tool that uses xml-files to define the build commands. It supports a wide range of tasks and if you for some reason can't find one for your needs you can always create your own (http://ant.apache.org/manual/develop.html).
There is no doubt that Ant is a good and powerful tool, but it has several well-known problems. First of all xml is not a programming language, this can make it difficult to do simple tasks like if-statements and loops (it is certainly possible to get it done, but often it becomes complex and hard to read). Secondly the build-files quickly become very verbose.
The example below shows two simple targets, compile and package.jar. Despite the problems mentioned earlier, I like Ant. You have total control of what is going on and it supports just about everything you would need to do in a build.
Maven<path id="lib.classpath">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.classpath" />
</target>
<target name="package.jar" depends="compile">
<jar basedir="${build.dir}" destfile="${jar.filepath}">
<manifest>
<attribute name="Main-Class" value="${main.class}" />
<attribute name="Class-Path" value="${classpath.entries}" />
</manifest>
<fileset dir="${res.dir}">
<include name="*.xml" />
</fileset>
</jar>
</target>
Maven has tried to solve most of the problems with Ant. Maven attempts to create a standard way to build projects and make the build process easy. Like Ant it uses xml-files for the build configuration. In addition to supporting regular tasks like compiling code it adds support for dependency management. The main issue with maven, in my opinion at least, is the lack of flexibility. You are basically locked in the default configuration, convention over configuration, making it a real pain if you need something different. There are other issues as well, like repository problems, but lets just go on with the example.
Continuing with the HelloWorld example, here is the pom.xml file:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>net.jarlehansen.helloworld.maven
</groupId>
<artifactId>maven-helloworld</artifactId>
<name>Maven HelloWorld</name>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>net.jarlehansen.helloworld.maven.HelloWorldMain
</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
When following the standard Maven project layout (http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html) it will compile and package the source code. In this case a jar-file is created.Gant
Gant tries to take a different approach, instead of using xml it supports Ant tasks with Groovy. By getting rid of the xml and adding an actual programming language it should solve all the problems right? Well, I haven't used it in any large projects, but I must admit I really like the idea.
The example shows how it uses the same tasks as Ant, but with Groovy syntax:
Gradle
includeTargets << gant.targets.Clean
cleanDirectory << targetDir
ant.path(id : 'libClasspath') {
fileset(dir : libDir, includes : '*.jar')
}
target(compile : 'Compiles source code') {
depends(init)
echo('compile')
ant.javac(srcdir : srcDir, destdir : buildDir, classpathref : 'libClasspath')
}
target(packageJar : 'Package the class files in a jar file') {
depends(compile)
echo('packageJar')
ant.jar(destfile : jarFilepath, basedir : buildDir) {
manifest() {
attribute(name : 'Main-Class', value : 'net.jarlehansen.helloworld.gant.HelloWorldMain')
attribute(name : 'Class-Path', value : '../lib/spring.jar ../lib/commons-logging.jar')
}
fileset(dir : resDir, includes : '*.xml')
}
}
setDefaultTarget (packageJar)
Gradle tries to behave more like Maven than Ant. Like Gant, it uses Groovy. And instead of the flexibility issues with Maven, it offers the best of both worlds. You can use the conventions from Maven, if you want to. Another pleasant sight is that Ant tasks are first class citizens. I really can't stand the AntRun plugin for Maven. In Gradle it is very simple to use Ant tasks, for example: ant.echo('hello'). One of the major issues I have found with both Gant and Gradle are the lack of IDE support. This will probably improve when these tools get more mature, but at the moment it is not available.
The example shows how Gradle can use the Maven repository to download the dependencies. It also compiles and packages the jar-file just like all the other examples (this is due to the 'java'-plugin):
ConclusionusePlugin('java')
sourceCompatibility = '1.5'
targetCompatibility = '1.5'
project.group = "net.jarlehansen.helloworld.gradle"
project.version = "1.0.0"
manifest.mainAttributes("Main-Class" : "net.jarlehansen.helloworld.gradle.HelloWorldMain",
"Class-Path" : "../lib/spring-2.5.6.jar ../lib/commons-logging-1.1.1.jar")
defaultTasks 'libs'
dependencies {
addMavenRepo()
compile "org.springframework:spring:2.5.6"
compile "commons-logging:commons-logging:1.1.1"
}
What is the best build tool? In my opinion the use of Groovy scripts for the builds makes a lot sense. And I must admit that both Gant and Gradle has a lot of potential. Hopefully the IDE support will arrive soon. In any case I will start using Gradle on a regular basis.
References
- Ant vs Maven, Episode 2 : Gant or Gradle? - http://codetojoy.blogspot.com/2008/10/ant-vs-maven-episode-2-gant-or-gradle.html
- alternatives to ant: gant, gradle and pjmake - http://blog.punchbarrel.com/2008/09/29/alternatives-to-ant-gant-gradle-and-pjmake/
- Why maven sucks! - http://www.jumpingbean.co.za/blogs/mark/maven_problems
- The Problem With Maven - http://www.alittlemadness.com/2007/08/01/the-problem-with-maven/
- XML is not the build system you're looking for - http://paulgrenyer.blogspot.com/2008/08/xml-is-not-build-system-youre-looking.html
- Maven - Pain = Gradle? - http://www.alittlemadness.com/2008/11/28/maven-pain-gradle/