This post has been migrated to http://www.thinkcode.se/blog/2014/07/02/comparing-maven-and-gradle
I have been using Maven for a long time. I used to use Ant and it took me a while to get used to Maven and accept the Maven way. Reading a blog post from Neal Ford Why Everyone (Eventually) Hates (or Leaves) Maven got me thinking. He talks about the popularity of 4GL, Fourth Generation Languages, during the 1990s and why they never really took off. The idea was great, but they were not able to solve the entire problem good enough. They solved perhaps 80% easily and the rest was harder and the last part was even harder to solve. The customers want this last part as well and that is the reason why we use general purpose programming languages today.
I used Paradox to build a system for a customer a long time ago. I was able to solve most of their problems.
One thing though, there was an error situation and the customer demanded a correct error message. My problem was that it was a system error that came from the runtime environment that I couldn’t control. My solution? To patch the binary that I delivered my application with. I replaced the error message with another message. I was lucky, the message I needed was one character shorter so the binary format was never changed. I am not sure that it was legal, I never asked Borland about it. But the error message became correct and the customer was happy and so was I.
Maven solves 80 – 90% of my build problems. Often, actually very often, more than that. But sometimes I face problems I can’t solve. I have written a number of Maven plugins for those cases. But it might be easier to use a build tool where I have access to a general purpose programming language instead. This is where Gradle comes into the picture. You write your build script using Groovy and have access to a complete programming language.
I will create two projects so I can be able to compare Maven and Gradle. The projects should do the same things. I will try to keep them as small and equal as possible. They should have a dependency to JUnit so I can write unit tests and they should run my unit tests.
Let me start with the Maven pom.
This really easy to read if you are used to read Maven poms. I define a name, a version and a dependency.
A Gradle project that does more or less the same looks like this:
I define that I want to use the Java plugin for a Java project. I define a version. The artifact id will be the same as the directory the module lives in. I haven’t understood how I should specify a group id. I added a dependency to a TDD framework in the testCompile group. This is the equivalent to the test scope in Maven. The last thing I need to do is to select the repository where I want to get the dependency from. This build file will run my unit tests. This is also easy to read, even if you never have read a gradle build file before.
One important difference between Maven and Gradle is that you have to define the repository you want to use in Gradle. Maven comes with a predefined repository. I define that I want to use Maven central in my build.gradle file.
15 lines of xml became 11 lines of Groovy, counting whitespace. Even if I like Maven, this is much easier to read.
Gradle has many tasks defined in plugins. I defined that I wanted to work with a Java project and applied the Java plugin. If I don’t need to do anything additional, then I don’t see a large difference between Gradle and Maven at this stage. The only major difference seems to be the syntax, xml or Groovy. The syntax may be a deal breaker for you, it isn’t for me.
The advantage with Gradle will be apparent the day I want to do something that is out of the box. I have the full power of a general purpose programming language at my disposal that day. This freedom comes with the risk that I create a monster that is hard to maintain. But fighting Maven may create a similar monster so I hope it will not be the case.