There are some battles that never end. It can only happen when both opponents are mighty strong!
When it come to the build mechanism to use for a project, Maven vs Gradle is one such battle. Internet is filled with fierce defense and counter attacks with developers preferring one over the other. Today, we hope to add fuel to the fire by sharing our learning in trying to use them in a real world project.
We assume you are familiar with at-least Maven to appreciate the article. A quick summary of Maven and Gradle.
A game changer introduced in 2002 after developers suffered years of sweat and toil with complex ant scripts
Great (and simple) dependency management
Maven enforced a directory structure for projects, thereby introducing a ‘standard’ layout for projects
Identifies each build artifact using G:A:V. Artifacts can also be stored in a repository such as Nexus
Captain Obvious – Maven’s pom.xml is based on xml format. So, it is declarative by nature
Maven plugins can be used to perform anything that isn’t covered by the normal build process. There is a sea of plugins available out there, with every major vendor supporting a maven version of the plugin
Maven supports a huge number of build life-cycle steps
Maven integrates well with many 3rd party tools involved in the software build process, such as CI servers, artifact repository systems, code coverage plugins etc.
Relatively new entry, first introduced in 2007 but gained a lot of traction from only around 2010. In 2013, Google chose Gradle as the build system for their Android projects.
Uses Maven’s directory structure, but could also be customized
Has it own central repository, but can also use Maven’s repository to manage dependencies
Utilizes the G:A:V format to identify artifacts, same as Maven
Is based on Groovy, a programming language. So, instead of xml’s, the build script will be in Groovy code
Ever increasing number of grade plugins, most big vendors have Gradle versions of the plugins
So, Which one is better between Maven and Gradle?
Recently, we worked on a green field JavaEE project and had to take this decision. We created a prototype of both Gradle and Maven projects. In order to decide on the tool of choice, we conducted an experiment to understand how convenient it is to meet the following requirements :
Build Prototype Requirements
Multi-module project structure
Compile using JDK 1.8
Compile and package both java files and resource files
Ability to execute a task on the parent project and it automatically executes on all child projects
Support web services(Jax-ws) compilation
Generate Jax-ws stubs by using ws-gen and ws-import
Substitute certain tokens in some configuration files – for e.g. Replace the token HOSTNAME with the name of the server where the build is executing
Run unit tests
Run Integration tests – this needed to be a fully automated step that could be executed just by running a single build command. From our previous experience in writing integration tests with maven, we knew this involved creating custom wars, download and extract the JavaEE container using the build script(e.g. Wildfly), deploy data-source, install custom wars etc.
Generate final package (war file for server side and executable jar for client side)
Generate code coverage reports
Gradle is much more powerful than Maven because it brings the power of a real programming language to the build scripts.
We were a team of 4 developers and had tight schedules to release a product within an year
Only 1 of the 3 developers knew Groovy.
All 4 developers very well experienced in building Maven scripts
We decided to give a week to set up projects using both Gradle and maven. The aim was not to completely implement the requirements, but to get a feel for Gradle in about a week. Here are our observations from trying to use Gradle as the build system for the prototype.
10 significant Observations
As mentioned before, only 1 of the 3 developers knew Groovy, rest of the guys had to learn a new programming language to set up the builds. Although groovy has a lower learning curve for java developers, it still meant time spent learning something that wasn’t going to be used for any other part of the software
The setup for a simple JavaSE project and compilation was easy enough, with just the necessity of applying the plugin using – apply plugin: ‘java’. At this stage the build file looked clean and manageable
Token substitution i.e. replacing tags with run time values was straight forward
Setting up multi module was difficult than expected. Our aim was to create a war file for 2 of the sub-projects. It has to be programmatically specified what goes into the packaged version of each project, after significant amount of coding, we seemed to get half way to our destination but customization seemed too difficult to achieve without writing a lot more code for the build. So, we stopped at this point and did not want to spend much more time on it
Running unit tests was straight forward
Gradle uses Groovy – a full-fledged programming language. Gradle makes no intention of hiding that fact. Their intention was to provide the power of programming languages to use in the build script – something that the predecessors such as ant and maven lack
We knew that because groovy is a programming language, we could have “bugs” in our build script/code. This was a worrying fact, and we had not considered this aspect before. On the other hand, Maven usage was straight forward and in most cases, XSD validation of the pom.xml was sufficient to identify errors
We skipped executing the integration tests since it seemed too complex to create custom code to get it functioning fully in a day or so. Arquillian(our integration test framework) did not have much information on usage with Gradle.
Generating the code coverage reports was straight forward.
Gradle support for any given plugin/product is much harder to find compared to Maven. The amount of documentation (both in terms of official documentation and on the dev forums) is sparse compared to Maven.
Gradle uses Groovy. Because groovy is a programming language, we could have “bugs” in our build script/code.
At the end of the experimentation, the fact that stood out for us is the amount of effort needed to write the build script(Groovy code) and to resolve bugs. The real benefit of Gradle seems to be when there is customization needed in both the structure of the project and also the build artifacts. However, we had a standard JavaEE project and it was much easier to use Maven. There are no neat “plugin usage” documentations like the ones that exist for most maven plugins.
It is however very true that Gradle is much more powerful than Maven because it brings the power of a real programming language to the build scripts. It is no surprise that big companies are using Gradle to customize their build chain. It is probable that most of these bigger companies have large number of people working on maintaining the build code. We had a humble team of 4 people. We concluded that for a small team such as ours, writing “ real code” for the build scripts was not practical, especially when out project was supposed to be a standard JavaEE project
On a closing thought, if you are wondering how long it took us to write the equivalent Maven script – It took a single person 2 days to get the prototype working. So, in the end the choice was obvious for us – we chose Maven.