Why use Gradle instead of Ant or Maven? [closed]

Solution 1:

I don't use Gradle in anger myself (just a toy project so far) [author means they have used Gradle on only a toy project so far, not that Gradle is a toy project - see comments], but I'd say that the reasons one would consider using it would be because of the frustrations of Ant and Maven.

In my experience Ant is often write-only (yes I know it is possible to write beautifully modular, elegant builds, but the fact is most people don't). For any non-trivial projects it becomes mind-bending, and takes great care to ensure that complex builds are truly portable. Its imperative nature can lead to replication of configuration between builds (though macros can help here).

Maven takes the opposite approach and expects you to completely integrate with the Maven lifecycle. Experienced Ant users find this particularly jarring as Maven removes many of the freedoms you have in Ant. For example there's a Sonatype blog that enumerates many of the Maven criticisms and their responses.

The Maven plugin mechanism allows for very powerful build configurations, and the inheritance model means you can define a small set of parent POMs encapsulating your build configurations for the whole enterprise and individual projects can inherit those configurations, leaving them lightweight. Maven configuration is very verbose (though Maven 3 promises to address this), and if you want to do anything that is "not the Maven way" you have to write a plugin or use the hacky Ant integration. Note I happen to like writing Maven plugins but appreciate that many will object to the effort involved.

Gradle promises to hit the sweet spot between Ant and Maven. It uses Ivy's approach for dependency resolution. It allows for convention over configuration but also includes Ant tasks as first class citizens. It also wisely allows you to use existing Maven/Ivy repositories.

So if you've hit and got stuck with any of the Ant/Maven pain points, it is probably worth trying Gradle out, though in my opinion it remains to be seen if you wouldn't just be trading known problems for unknown ones. The proof of the pudding is in the eating though so I would reserve judgment until the product is a little more mature and others have ironed out any kinks (they call it bleeding edge for a reason). I'll still be using it in my toy projects though, It's always good to be aware of the options.

Solution 2:

Gradle can be used for many purposes - it's a much better Swiss army knife than Ant - but it's specifically focused on multi-project builds.

First of all, Gradle is a dependency programming tool which also means it's a programming tool. With Gradle you can execute any random task in your setup and Gradle will make sure all declared dependecies are properly and timely executed. Your code can be spread across many directories in any kind of layout (tree, flat, scattered, ...).

Gradle has two distinct phases: evaluation and execution. Basically, during evaluation Gradle will look for and evaluate build scripts in the directories it is supposed to look. During execution Gradle will execute tasks which have been loaded during evaluation taking into account task inter-dependencies.

On top of these dependency programming features Gradle adds project and JAR dependency features by intergration with Apache Ivy. As you know Ivy is a much more powerful and much less opinionated dependency management tool than say Maven.

Gradle detects dependencies between projects and between projects and JARs. Gradle works with Maven repositories (download and upload) like the iBiblio one or your own repositories but also supports and other kind of repository infrastructure you might have.

In multi-project builds Gradle is both adaptable and adapts to the build's structure and architecture. You don't have to adapt your structure or architecture to your build tool as would be required with Maven.

Gradle tries very hard not to get in your way, an effort Maven almost never makes. Convention is good yet so is flexibility. Gradle gives you many more features than Maven does but most importantly in many cases Gradle will offer you a painless transition path away from Maven.

Solution 3:

This may be a bit controversial, but Gradle doesn't hide the fact that it's a fully-fledged programming language.

Ant + ant-contrib is essentially a turing complete programming language that no one really wants to program in.

Maven tries to take the opposite approach of trying to be completely declarative and forcing you to write and compile a plugin if you need logic. It also imposes a project model that is completely inflexible. Gradle combines the best of all these tools:

  • It follows convention-over-configuration (ala Maven) but only to the extent you want it
  • It lets you write flexible custom tasks like in Ant
  • It provides multi-module project support that is superior to both Ant and Maven
  • It has a DSL that makes the 80% things easy and the 20% things possible (unlike other build tools that make the 80% easy, 10% possible and 10% effectively impossible).

Gradle is the most configurable and flexible build tool I have yet to use. It requires some investment up front to learn the DSL and concepts like configurations but if you need a no-nonsense and completely configurable JVM build tool it's hard to beat.

Solution 4:

Gradle nicely combines both Ant and Maven, taking the best from both frameworks. Flexibility from Ant and convention over configuration, dependency management and plugins from Maven.

So if you want to have a standard java build, like in maven, but test task has to do some custom step it could look like below.

build.gradle:

apply plugin:'java'
task test{
  doFirst{
    ant.copy(toDir:'build/test-classes'){fileset dir:'src/test/extra-resources'}
  }
  doLast{
    ...
  }
}

On top of that it uses groovy syntax which gives much more expression power then ant/maven's xml.

It is a superset of Ant - you can use all Ant tasks in gradle with nicer, groovy-like syntax, ie.

ant.copy(file:'a.txt', toDir:"xyz")

or

ant.with{
  delete "x.txt"
  mkdir "abc"
  copy file:"a.txt", toDir: "abc"
}