Java Build Tools: Ant vs Maven vs Gradle

In the beginning there was Make as the only build tool available. Later on it was improved with GNU Make. However, since then our needs increased and, as a result, build tools evolved.

JVM ecosystem is dominated with three build tools:

Ant with Ivy

antAnt was the first among “modern” build tools. In many aspects it is similar to Make. It was released in 2000 and in a short period of time became the most popular build tool for Java projects. It has very low learning curve thus allowing anyone to start using it without any special preparation. It is based on procedural programming idea.

After its initial release, it was improved with the ability to accept plug-ins.

Major drawback was XML as the format to write build scripts. XML, being hierarchical in nature, is not a good fit for procedural programming approach Ant uses. Another problem with Ant is that its XML tends to become unmanageably big when used with all but very small projects.

Later on, as dependency management over the network became a must, Ant adopted Apache Ivy.

Main benefit of Ant is its control of the build process.


mavenMaven was released in 2004. Its goal was to improve upon some of the problems developers were facing when using Ant.

Maven continues using XML as the format to write build specification. However, structure is diametrically different. While Ant requires developers to write all the commands that lead to the successful execution of some task, Maven relies on conventions and provides the available targets (goals) that can be invoked. As the additional, and probably most important addition, Maven introduced the ability to download dependencies over the network (later on adopted by Ant through Ivy). That in itself revolutionized the way we deliver software.

However, Maven has its own problems. Dependencies management does not handle conflicts well between different versions of the same library (something Ivy is much better at). XML as the build configuration format is strictly structured and highly standardized. Customization of targets (goals) is hard. Since Maven is focused mostly on dependency management, complex, customized build scripts are actually harder to write in Maven than in Ant.

Maven configuration written in XML continuous being big and cumbersome. On bigger projects it can have hundreds of lines of code without actually doing anything “extraordinary”.

Main benefit from Maven is its life-cycle. As long as the project is based on certain standards, with Maven one can pass through the whole life cycle with relative ease. This comes at a cost of flexibility.

In the mean time the interest for DSLs (Domain Specific Languages) continued increasing. The idea is to have languages designed to solve problems belonging to a specific domain. In case of builds, one of the results of applying DSL is Gradle.


gradleGradle combines good parts of both tools and builds on top of them with DSL and other improvements. It has Ant’s power and flexibility with Maven’s life-cycle and ease of use. The end result is a tool that was released in 2012 and gained a lot of attention in a short period of time. For example, Google adopted Gradle as the default build tool for the Android OS.

Gradle does not use XML. Instead, it had its own DSL based on Groovy (one of JVM languages). As a result, Gradle build scripts tend to be much shorter and clearer than those written for Ant or Maven. The amount of boilerplate code is much smaller with Gradle since its DSL is designed to solve a specific problem: move software through its life cycle, from compilation through static analysis and testing until packaging and deployment.

Initially, Gradle used Apache Ivy for its dependency management. Later own it moved to its own native dependency resolution engine.

Gradle effort can be summed as “convention is good and so is flexibility”.

Code examples

We’ll create build scripts that will compile, perform static analysis, run unit tests and, finally, create JAR files. We’ll do those operations in all three frameworks (Ant, Maven and Gradle) and compare the syntax. By comparing the code for each task we’ll be able to get a better understanding of the differences and make an informed decision regarding the choice of the build tool.

First things first. If you’ll do the examples from this article by yourself, you’ll need Ant, Ivy, Maven and Gradle installed. Please follow installation instructions provided by makers of those tools. You can choose not to run examples by yourself and skip the installation altogether. Code snippets should be enough to give you the basic idea of how each of the tools work.

Code repository contains the java code (two simple classes with corresponding tests), checkstyle configuration and Ant, Ivy, Maven and Gradle configuration files.

Let’s start with Ant and Ivy.

Ant with Ivy

Ivy dependencies need to be specified in the ivy.xml file. Our example is fairly simple and requires only JUnit and Hamcrest dependencies.


<ivy-module version="2.0">
    <info organisation="org.apache" module="java-build-tools"/>
        <dependency org="junit" name="junit" rev="4.11"/>
        <dependency org="org.hamcrest" name="hamcrest-all" rev="1.3"/>

Now we’ll create our Ant build script. Its task will be only to compile a JAR file. The end result is the following build.xml.


<project xmlns:ivy="antlib:org.apache.ivy.ant" name="java-build-tools" default="jar">

    <property name="src.dir" value="src"/>
    <property name="build.dir" value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir" value="${build.dir}/jar"/>
    <property name="lib.dir" value="lib" />
    <path id="">
        <fileset dir="${lib.dir}" />

    <target name="resolve">
        <ivy:retrieve />

    <target name="clean">
        <delete dir="${build.dir}"/>

    <target name="compile" depends="resolve">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref=""/>

    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${}.jar" basedir="${classes.dir}"/>


First we specify several properties. From there on it is one task after another. We use Ivy to resolve dependencies, clean, compile and, finally, create the JAR file. That is quite a lot of configuration for a task that almost every Java project needs to perform.

To run the Ant task that creates the JAR file, execute following.

ant jar

Let’s see how would Maven does the same set of tasks.



<project xmlns=""





To run the Maven goal that creates the JAR file, execute following.

mvn package

The major difference is that with Maven we don’t need to specify what should be done. We’re not creating tasks but setting the parameters (what are the dependencies, what plugins to use…). This shows the major difference between Ant and Maven. Later promotes the usage of conventions and provides goals (targets) out-of-the-box. Both Ant and Maven XML files tend to grow big with time. To illustrate that, we’ll add Maven CheckStyle, FindBugs and PMD plugins that will take care of static analysis. All three are fairly standard tools used, in one form or another, in many Java projects. We want all static analysis to be executed as part of a single target verify together with unit tests. Moreover, we should specify the path to the custom checkstyle configuration and make sure that it fails on error. Additional Maven code is following:



To run the Maven goal that runs both unit tests and static analysis with CheckStyle, FindBugs and PMD, execute following.

mvn verify

We had to write a lot of XML that does some very basic and commonly used set of tasks. On real projects with a lot more dependencies and tasks, Maven pom.xml files can easily reach hundreds or even thousands of lines of XML.

Here’s how the same looks in Gradle.



apply plugin: 'java'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

version = '1.0'

repositories {

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'

Not only that the Gradle code is much shorter and, to those familiar with Gradle, easier to understand than Maven, but it actually introduces many useful tasks not covered with the Maven code we just wrote. To get the list of all tasks that Gradle can run with the current configuration, please execute the following.

gradle tasks --all

Clarity, complexity and the learning curve

For newcomers, Ant is the clearest tool of all. Just by reading the configuration XML one can understand what it does. However, writing Ant tasks easily gets very complex. Maven and, specially, Gradle have a lot of tasks already available out-of-the-box or through plugins. For example, by seeing the following line it is probably not clear to those not initiated into mysteries of Gradle what tasks will be unlocked for us to use.


apply plugin: 'java'

This simple line of code adds 20+ tasks waiting for us to use.

Ant’s readability and Maven’s simplicity are, in my opinion, false arguments that apply only during the short initial Gradle learning curve. Once one is used to the Gradle DSL, its syntax is shorter and easier to understand than those employed by Ant or Maven. Moreover, only Gradle offers both conventions and creation of commands. While Maven can be extended with Ant tasks, it is tedious and not very productive. Gradle with Groovy brings it to the next level.

64 thoughts on “Java Build Tools: Ant vs Maven vs Gradle

  1. Foobo

    Gradle is nice if your developers’ time is worth nothing.
    Yes, the example code looks nice, but it’s a lot less declarative than maven, simply because the kind of developer that wants to write scripts instead of XML WILL write scripts, and they make your build unreadable (I’m in a gradle project right now, but I don’t know it too well; I only know what the build does because gradle prints out the tasks it executes).

    Also, while ant is quite fast (though still slower than Eclipse) and maven is – by now – slower but ok, gradle is incredibly, annoyingly, very very painfully abysmally slow. Yes, I know the daemon. It doesn’t work, it only causes the “clean” goal to fail on Windows, because some background gradle process is holding my compiled/copied files hostage.

    So in the end, rather spend an hour or two more on an ant or maven build (seriously, how complex is your build??), and all your developers will save LOTS of build time every single day.

    1. smb

      As a programmer, I want to spend my time and energy on writing code, not on my build tools. That means that I look at this code once in a blue moon: I fix broken things as quickly as I can and move on. Don’t want to have to remember any details; don’t want to have to learn any new tricks. Sure, there’s lots of cool stuff, but I’ve never had the time to play with them. What would my boss say if I spent 10% of my schedule on build tools (minimum time needed to stay abreast of a language/system)?

      The best solution would be to never have to deal with this at all (let an IDE take care of it).

      I would also stress that Gradle, as implemented in Android Studio, is too slow to be productive. For most projects (mine rarely last more than a few months), MAKE + Git works perfectly well.

  2. french guest

    @smb : I’m a developer too. Your opinion about build tools make me writing this post.
    Where stops our ‘dev’ responsability and where begins those of ‘ops’ ? At the result produced by an IC tools such as Jenkins. So, the build part is our concern.
    Thanks for reading.

    1. Viktor Farcic Post author

      It’s difficult to answer where dev. responsibility stops. It depends on the type of the project and the team structure. My opinion is that dev. responsibility is to deliver software. Delivery ends when software is working in production. This point of view is difficult to defend when project team is divided into silos (dev., testers, IEs…). However, having that division removes responsibility (i.e. it’s testers job to ensure quality). When silos are removed (one team, no departments), safety net is removed and quality increases. Long story short, I’d say that, when possible, it is devs responsibility to deliver from the start until the end.

  3. fhomasp

    Actually, I disagree completely on your Maven view. Where on earth would you say that there’s less flexibility with Maven?
    Maven uses “convention over configuration”, quite an important paradigm when talking about Maven.
    Maven will by default structure your project in a certain way, unless you specify otherwise (which you shouldn’t, there’s likely not a valid reason to do so).

    And if your Maven poms are getting quite large, there’s something you’re not doing right. Maven has a hierarchial structure which allows you to group common tasks in parent pom files.

    There’s a reason that half of the Java world uses Maven.

    1. Viktor Farcic Post author

      Gradle also uses “convention over configuration” and structures your project in a certain way. In those aspects Maven and Gradle are the same with exception that Gradle has much shorter and (to me) easier to understand configuration. On top of that, Gradle allows you to program if, for whatever reason, something doesn’t come from “convention”.

      Whether configuration files are large or not depends on what is one used to. However, any Gradle file on average is at least several times shorter than its equivalent in Maven.

      The reason that half of the Java world uses Maven is historical. It is older than Gradle. One can say that there is a reason that people and companies are switching from Maven to Gradle. Android studio is only one of many examples. There is LinkedIn, Netflix, Siemens…

      There is no one-fits-all solution. Even Ant has some advantages over Maven and Gradle. One should try out different options before making judgement. I worked on many projects using Ant (with and without Ivy), Maven, Gradle, SBT (not mentioned in this article). As it is now, Gradle is my favorite. It came after Maven and corrected some of mistakes it has. Similar thing happened with Ant when Maven took over.

      Would you share with us what bothers you with Gradle? What makes Maven superior?

      1. fhomasp

        Actually I came here searching more info about Gradle, as I don’t know much about it. Hence I never stated that Gradle is better or worse than the other.
        I can about Ivy though.
        I have worked with Ant and Ivy and I wouldn’t want to be caught dead using it. Horrible plugin support for Eclipse, which is of course nothing new and the same can be said about Maven plugins in Eclipse. Though slightly less error-prone.
        However I won’t be too specific because I’ve only worked with it on a project that was even more horribly configured than the Ivy Eclipse plugin itself. And I also hate working at places where an IDE is forced on me. This is also why I like Maven a lot because it takes a lot of IDE specific stuff away from the project. The question is not “does it work in Eclipse or ” anymore, but “does it work in Maven”.

        For me the best tool is the tool that has the best IDE support. I prefer to work with IntelliJ IDEA and for that, the best support is for Maven. But getting deeper into that is not really in the scope of your article 🙂

        One extra note though, one can also program for Maven. I’ve written several MOJO (Maven plugins) over the years to solve a specific problem that would otherwise require too much XML configuration. It’s not hard to do, although it seems easier with Gradle. But there IntelliJ IDEA, with its great Maven support, it’s not hard at all.

  4. BloodGain

    From the looks of it, IntelliJ IDEA added quite a bit of support for Gradle in v13, which has been out since last December. If they keep up with their previous release history, that support should get even better in a couple of months with v14.

  5. jbuilder

    Regarding : The reason that half of the Java world uses Maven is historical.
    That is not what these guys are says:

    Just to add, when talking about huge and large XML poms, is that due to you trying to plugin the world into the project?
    Why would you do that?
    What about static analyzers using sonar, oh you dont have automated Jenkins with sonar? stick to your eclipse plugins then!
    IOM you should declare dependencies and specify your java version, and do not overwork your pom.xml.

    But there are for sure situations when gradle would suit your needs, lets say when you really need to twist the arm of maven structure and work out of its bounderies.

    come on guys, javac then move some files and zip, thats what build tools are about.

    1. martin

      I agree @jbuilder and nowdays analyses your code, dont attempt to maintain these in your pom.xml!

      1. Viktor Farcic Post author

        Are you saying that one should commit any code to the repo and wait for CIs to find static analysis errors (CheckStyle, PMD, CPD, …) and mark the build as failed? In larger teams that would mean that your CI builds will be red most of the time since . Another point is that Cloud CIs generally use whatever you have in your POM/Gradle. They will execute check/verify task.

  6. Pingback: Java – Maven o Gradle | Blogging googling

  7. xiaokun

    Different tools have different use scenarios. For simple project, user friendly is in the first place. But when goes to big projects which have complex dependencies. The efficiency should be the most important one in most cases. My only concern is whether Gradle has a good support of incremental build? Does it have a better performance than ant or maven?

  8. Viktor Farcic Post author

    I assume that you wanted to say incremental compiling. Whether incremental compiling works well or not depends more in JDK that build tool one is using. As far as I know, JDK does not support it (unless it was introduced in JDK 8). For the sake of comparison, Scala does have incremental compiling and it works pretty well. I have a “watcher” assigned to my Scala projects that compiles to classes every time there is any change to the source code (and on top of that it runs tests). Compilation itself is performed only with source files that were changed and that speed up the process a lot (besides the fact that Scala compilation is in general slower than Java).

    Incremental tasks (or builds), on the other hand, are supported and only those related with files that were changed are run. That feature works very well.

    Have I missunderstood the question?

    1. huotuotuofly

      yes.. seems javac will support incremental compiling in next jdk version. I will try gradle with its parallel building feature. Thanks

  9. chrisco

    For the simple fact that someone had the guts to create a new tool that didn’t require configuration to be written in brain dead, massively verbose and ‘used everywhere for no good reason’ XML I’m definitely going to investigate Gradle and look at moving our existing ant and maven scripts over to it.

    I actually really like the fact that plugins can be written in a Java – if that’s your native tongue why not use it!

  10. Pingback: Ant, Maven, Graddle??? wtf??? Interesting comparison article: | Pavel Birioukov

  11. Pingback: Build Tool คืออะไร? Gradle คืออะไร? Ant คืออะไร? |

  12. Seiti

    you said that gradle uses ivy for dependencies but that’s false there is no default repository, you have to choose between maven or ivy.

    1. Viktor Farcic Post author

      You’re right. Information I put is obsolete. Gradle used Ivy for dependecy resolution but later on switched to it’s own engine that, among other things, supports both Maven and Ivy.

  13. Pingback: Java Build Tools: Ant vs Maven vs Gradle | Ranjan Kumar

  14. Steve Cohen

    “Next article with go deeper into Gradle and explain in more details its integration with Groovy.”

    Was this article ever written? Not finding it in Google or this site.

  15. Pingback: Open Source Build System Evaluation in the Age of Continuous Delivery: Part 1 - Gradle

  16. Pingback: Java Build Tools: Ant vs Maven vs Gradle |

    1. Viktor Farcic Post author

      While there are those using sbt with Java, it never really lifted of. Sbt remains the weapon of choice for Scala developers. Since this article is oriented towards Java lovers, I don’t think that it makes sense to put sbt into this group.

  17. Pingback: Why Gradle? | coding

  18. Pingback: Java Build Tools | Happy coding

  19. Pingback: Po pierwsze: Gradle | devBlog

  20. Pingback: Graddle vs Maven vs Ant | Graddle

  21. Chris

    Would be great to do another pass on this and fix up the examples. I could only get the Gradle build to run, and even then had to modify some code. I guess this is perhaps a good indicator of the ease of interaction for build tools, me having never used any of these before, Gradle was the most approachable to do this.

    Thanks for the article!

    1. Viktor Farcic Post author


      I won’t be able to dedicate time to update the code and the article within the next two weeks. Would you try it yourself and create a pull request?

  22. Pingback: How To Compile Java Program Through Ant | Goods News

  23. Pingback: swnek.coding » Gradle – Narzędzie do budowy projektów

  24. Jose Miguel

    Just migrating from maven to gradle due Android “looks” to work better with gradle. Gradle is not finished… no a good release and versioning process. Some plugins there but not maintained, very poor. I’ve linked with jenkins, and after some days I’ve the Continuous integration process working with versioning included, but the same with maven is done in two hours.
    Gradle supports more things, I agree, but things that are not normally needed attached to a build process.

  25. Pingback: Java Build Tools: Ant vs Maven vs Gradle – Computer Stuff (Mainly)

  26. Pingback: Gradle for Android 系列:为什么 Gradle 这么火 | 海沙

  27. Pingback: maven, ivy, ant | mvnblog

  28. Pingback: Java构建工具:Ant vs Maven vs Gradle – Michael's Blog

  29. Pingback: Java构建工具:Ant vs Maven vs Gradle – Michael's Blog

  30. Pingback: Agile toolbox for Java workshop - LeanDevjavascript:Duplicator.getNewURL('url_new')

  31. Pingback: Agile toolbox for Java workshop - LeanDevjavascript:Duplicator.getNewURL('url_new')

  32. Pingback: The Journey To Android Monorepo: The History Of Uber Engineering’s Android Codebase Organization - Engineering News

  33. Pingback: Gradle vs. Maven | Unsekhable

  34. Ravinder Sudhini

    English grammar minor change:
    current text: well conflicts
    new text: conflicts well
    Maven has its own problems. Dependencies management does not handle well conflicts between different versions of the same library.

  35. Martin

    Nice desription of the differences. With your examples it’s easy to understand and make a decision using the right “make-file”

  36. Pingback: Android – 如何在Android Project中使用ThreeTenABP – includeStdio

  37. Pingback: The Journey To Android Monorepo: The History Of Uber Engineering’s Android Codebase Organization | Uber Engineering Blog

  38. Pingback: The Journey To Android Monorepo: The History Of Uber Engineering's Android Codebase Organization | Uber Engineering Blog

  39. Pingback: Android 프로젝트에서 ThreeTenABP를 사용하는 방법 - 질문답변

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s