a little madness

A man needs a little madness, or else he never dares cut the rope and be free -Nikos Kazantzakis

Zutubi

Maven – Pain = Gradle?

Being in the continuous integration game, it’s part of my job to keep an eye on build tools and technologies. Occasionally I hear of something interesting enough to try out, so when I next start a small project I’ll give it a go.

This time it is the turn of Gradle. From the Gradle website:

Gradle is a build system which provides:

  • A very flexible general purpose build tool like Ant.
  • Switchable, build-by-convention frameworks a la Maven (for Java and Groovy projects). But we never lock you
    in!
  • Powerful support for multi-project builds.
  • Powerful dependency management (based on Apache Ivy).
  • Full support for your existing Maven or Ivy repository infrastructure.
  • Support for transitive dependency management without the need for remote repositories and pom.xml
    or ivy.xml files (optional).
  • Ant tasks as first class citizens.
  • Groovy build scripts.

Build tools that leverage scripting languages such as Groovy, Ruby and Python are all the rage. This is undoubtedly a useful feature, but so common these days that it is not a differentiating factor. After all, just adding a more concise way to write procedural build scripts is not a big win. The focus needs to be on making builds as declarative as possible.

The current king of declarative builds in the Java world is undoubtedly Maven. However, as I have said in a previous post, the current implementation of Maven leaves a lot to be desired. Still, the Maven idea of build-by-convention is still a good one if it can be achieved in a flexible way. This, then, is what attracts me to Gradle — its specific goal of providing build-by-convention without the lock-in.

Installation

To begin, I set myself the lofty goal of writing a “Hello, World” build script. This gets me to the point where I have a working gradle installation. As I already had a JDK installed (the only external dependency), installation was as simple as:

$ wget http://dist.codehaus.org/gradle/gradle-0.4-all.zip
$ unzip gradle-0.4-all.zip

$ export GRADLE_HOME=”$(pwd)/gradle-0.4″
$ export PATH=”$PATH:$GRADLE_HOME/bin”
$ gradle -v
Gradle 0.4
Gradle buildtime: Tuesday, September 16, 2008 9:20:38 AM CEST
Groovy 1.5.5
Java 1.6.0_06
JVM 10.0-b22
JVM Vendor: Sun Microsystems Inc.
OS Name: Linux

Gradle build files are named “build.gradle”, so next I created a trivial example as follows:

createTask(‘hello’)
{
    println ‘Hello, world!’
}

The above is normal Groovy source code, executed in an environment provided by gradle. It defines a single task which is gradle’s equivalent of a target (almost like the combination of an Ant task and target). Executing this task gives:

$ gradle -q hello
Hello, world!
$

Note that the -q flag suppresses some gradle output.

A Simple Java Project

To test gradle’s claims of build-by-convention, I next put it to work on a simple Java project. Gradle’s build-by-convention support is implemented as “plugins” for different languages, with Java and Groovy plugins provided out of the box. The project to be built is a JavaDoc doclet, so the build just needs to compile Java source files into a single jar. To make life a little interesting, the project does not fit gradle’s default conventions in two ways:

  1. It should not be named after the containing directory.
  2. The source is located under “src/java”, not “src/main/java”.

These are truly simple customisations — so you would expect them to be easily configured. And indeed they are, as shown in the build.gradle file:

name = archivesBaseName = ‘com.zutubi.xmlrpc.doclet’
version = ‘0.1’

usePlugin(‘java’)
sourceCompatibility = 1.5

targetCompatibility = 1.5
srcDirNames = [‘java’]

The first line customises the project and jar file names, and the last line is used to override the default location for Java source files. With this build file in place, I can build the jar as follows:

$ gradle -q libs
$ ls build
classes com.zutubi.xmlrpc.doclet-0.1.jar reports test-classes test-results

That was pleasantly simple! The Java plugin also gives me a bunch of other tasks for free:

$ gradle -qt
**************************************************
Project :
Task :archive_jar [:test]
Task :clean []
Task :compile [:resources]
Task :dists [:libs]
Task :eclipse [:eclipseCp, :eclipseProject]
Task :eclipseClean []
Task :eclipseCp []
Task :eclipseProject []
Task :eclipseWtpModule []
Task :init []
Task :javadoc []
Task :libs [:archive_jar, :test]
Task :resources [:init]
Task :test [:testCompile]
Task :testCompile [:testResources]
Task :testResources [:compile]
Task :upload [:uploadDists, :uploadLibs]
Task :uploadDists [:dists]
Task :uploadInternalLibs [:libs]
Task :uploadLibs [:libs]

Conclusion

So far, gradle looks very promising. The example above is too simple to judge how it would fare on a larger, more challenging build, but it shows the basics are right: at least a simple case is simple. I hope to give it a try on a larger code base soon.

At the moment the gradle project is still in its infancy, so I’ll be keeping a keen eye on its development. Indeed, if it can achieve its stated goals it will become a build tool to reckon with, and a tough competitor for Maven.


Zutubi Pulse: Continuous Integration made easy
Does your project have a pulse? Try it for free
Liked this post? Share it!

2 Responses to “Maven – Pain = Gradle?”

  1. January 19th, 2009 at 1:29 am

    Basil Vandegriend says:

    Nice article. I had already checked out the Gradle getting started, but didn’t get a good sense of what the Java plugin does for you by convention. Your article did a good job communicating that and has gotten me even more interested in giving Gradle a try.

    I’m especially intrigued by Gradle’s integration with pre-existing Ant tasks. Any experience with that?

    Thanks!

  2. January 20th, 2009 at 12:37 am

    Jason says:

    Hi Basil,

    Thanks for the kind comment. I have been using Gradle a bit more now and do quite like it. Although the devs have put a lot of work into the User Guide there are still things that are mysterious, but the mailing list response time is pretty good so you can always post questions there too.

    Re: integration with Ant, Gradle achieves this via the nice AntBuilder that is part of Groovy:

    http://groovy.codehaus.org/Using+Ant+from+Groovy

    It gives you a succinct groovy syntax for calling Ant tasks.

Leave a Reply