Java Build Tool Comparison HJUG - April 29th, 2009 John Tyler Java Build Tool Comparison • • Desired Features The Contenders • • • • • • • • Ant + Ivy Maven Gradle Buildr Others Results Matrix Subjective Evaluation Which Would You Choose? Desired Features • • • • • • • • • • • • Dependency management Versioning Compile Java code, build jars Execute tests and report results, fail build on failed tests Run quality-check tools (PMD, Findbugs, Checkstyles) File generation (XmlBeans, Xsl, Velocity, AspectJ) Property expansion / token substitution Build vs. deploy vs. release Full control when needed Cross-platform IDE Support Documentation / Support Ant + Ivy Ant is ubiquitous Java-based build tool Uses XML “script” files Ivy is a dependency manager Artifact repository Dependency resolution, including transitive (Project A -> Hibernate -> CommonsCollections) Sync with external repositories Ant + Ivy Module dependencies are declared in ivy.xml <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <info organisation=“org.hjug" module=“myModule"/> <dependencies> <dependency org="org.apache" name="ant" rev="1.7.0"/> <dependency org="org.apache" name="axis" rev="1.2rc3"/> <dependency org="org.junit" name="junit" rev="4.4"/> </dependencies> </ivy-module> Ant + Ivy Add this to your Ant buildfile (build.xml) <project xmlns:ivy="antlib:org.apache.ivy.ant" name="pdk" default="default" basedir="."> … <!-- Ivy Taskdefs --> <path id="ivy.lib.path"> <fileset dir="C:/java-tools/apache-ivy-2.0.0" includes="*.jar"/> </path> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/> <!-- Reference Ivy settings --> <ivy:settings file="${basedir}/../ivysettings.xml"/> <target name="ivy.resolve" description="--> retrieve dependencies with ivy"> <ivy:retrieve pattern=“${lib.dir}/[conf]/[artifact].[ext]”/> </target> <target name="ivy.publish" description="--> publish artifacts to local repository"> <ivy:publish resolver=“local” pubrevision=“${version}”> <artifacts pattern=“dist/[artifact].[ext]”/> </ivy:publish> </target> Ant + Ivy Build steps defined and executed with Ant Dependencies managed with Ivy Ant targets to install, retrieve artifacts from Ivy repository Ant + Ivy Image copied from http://ant.apache.org/ivy/history/2.0.0/principle.html Maven Project is defined by POM (Project Object Model) Projects can contain sub-projects (modules) Based on recommended project structure (e.g. src/main/java, src/main/resources, src/test/java, …) Artifact-focused (i.e. What files does this build produce?) Heavy emphasis on default configuration Maven Build Lifecycle is defined as Phases, which execute sequentially 1. 2. 3. 4. 5. 6. 7. 8. Validate Compile Test Package Integration-test Verify Install Deploy Maven Each Phase can be made up of zero or more Goals (tasks) Project-specific configuration involves binding specific goals to specific phases (beyond the default settings) Extensible plugin system (called Mojos) Java-based or Ant-based Comprehensive set of third-party plugins available Gradle Built on top of Ant + Ivy Build DSL written in Groovy Uses Groovy AntBuilder ant.compile, ant.jar Plugins define common tasks to build different types of projects java, groovy, war, … Gradle Assumes Maven conventions for file locations (drop-in replacement for Maven) Can be altered with the convention object Can use existing Maven or Ivy repositories Buildr Built on Ruby Rake is similar to Ant (Ruby Make) RubyGems is similar to rpm (package manager, handles dependencies) Build script written in Ruby (internal DSL) Buildr Pre-defined tasks clean compile build upload install javadoc package test uninstall Buildr Assumes Maven conventions for file locations (drop-in replacement for Maven) Can be altered Can use existing Maven repositories Others Gant Rake EasyAnt Custom ? Out of the box Results Matrix Desired Feature Ant + Ivy Not supported Maven Gradle Buildr Doesn’t include html reports Doesn’t include html reports Dependency management Versioning manually Compile Java code, build jars Execute tests, report results, fail build on failed tests Run quality check tools (PMD, FindBugs, JavaDoc) 3rd party task libraries 3rd party plugins Manually Manually File generation (XmlBeans, XSL, Velocity, AspectJ) 3rd party task libraries 3rd party plugins Manually Manually Results Matrix cont’d Desired Feature Ant + Ivy Maven Out of the box Not supported Gradle Buildr Property expansion / token substitution Build vs. deploy vs. release Manually defined Full control when needed Custom XML “scripts” Write custom plugin or embedded Ant script Groovy code directly in build file Ruby code directly in build file Runs on JVM Runs on Ruby, may need to compile from source Cross-platform Runs on JVM Runs on JVM IDE Support Eclipse only Documentation / Support Excellent Growing but still inconsistent Decent project documentation, few articles Good project documentation, few articles Subjective Evaluation Ant, Ivy, Maven have been around the longest Restrictive vs. Open philosophy Smart defaults Dependency Management is a Good Thing™ Ant has by far the best documentation and examples available online Gradle is the least mature (but very promising) Buildr is very cool but has potential platform issues (Ruby vs. JRuby, 64-bit) Which Would You Choose?