Historically, developers compiled and linked their code through running compiler commands through terminal. Most of these commands were pretty much the same at the time, so they decided to create special “build tools”, that could save developers some time typing commands. As you can probably guess, it’s not reasonable to use the command line if you have many source code modules and they should be compiled and linked in a particular order.
The first solution that ever came up to handle this was Make, a scripting language that allowed a build script to be written as a series of compile-and-link steps. Later, a GNU version of Make offered additional features, such as dependency management and incremental building.
Nowadays we demand much more from our build tools. We need a comfortable way to run tests, deploy applications, generate documentation and many other needs too numerous to name here. And so the build tools have evolved. The Java ecosystem now has Maven, Gradle, Ant and some others (like Scala’s Simple Build Tool–SBT) were born to solve the oldest problem in programming–build automation.
So over the next couple of weeks, we’ll talk about Java’s three most-used build tools: Maven, Gradle and Ant. We’ll compare them and provide some advice regarding the situations in which one tool is ahead or behind the others.
Ant was the first of the so-called “modern build tools”, and is used for automating build process. In theory, it is kind of like Make, without Make’s wrinkles. It is implemented in Java and used mostly for Java projects. The first public release of Ant was in 2000, and it quickly became most popular build tool for Java projects thanks to being platform independent (like Java), having low barriers for getting set up, and providing repeatable builds. Later, it also gained the ability to accept plugins.
However, Ant was criticized for having some drawbacks. Build scripts are written in XML, which is hierarchical by nature and not suitable for procedural programming, something often needed in build scripts. Ant is often claimed to be overly verbose, which means it can eventually make build scripts for large projects unmanageably big.
Maven was first released in 2004 and designed to improve upon some of the issues developers had with Ant and other build tools at the time. Maven’s biggest achievements are considered to be the introduction of project structure conventions, dependency management and a central artifact repository, Maven Central.
Maven still uses XML for writing a build file (pom.xml), but the structure is very different because it became declarative. Now developers don’t have to write down all the commands that lead to some goals, but instead he describes the structure of the project (if it differentiates from the conventions) and Maven itself provides the available targets that a programmer can invoke. Plus, Maven is capable of downloading dependencies through a network.
Gradle is the youngest build tool of the three and its developers tried to combine Ant’s power and flexibility with Maven’s dependency management and conventions to create nice and shiny build tool. After several years of developers, Gradle v1.0 was released in 2012, and has quickly started to gain popularity. It’s developing really fast and already adopted by some big enterprises–Gradle, for example, was selected to be the build tool for Google’s Android OS.
One interesting point is that with Gradle, XML is not used anymore–instead, developers have a Domain Specific Language (DSL) based on the JVM language Groovy, which was invented so that developers could ditch the verbosity of XML and write more simple and clear statements. This has sparked a debate among users as to whether the standard, easily-understandable (but long-winded) style of XML is better or worse than DSL.
DSL or XML?
There is a lot to cover when it comes to build tools, but for now we just can compare using DSL and XML, since there is a lot of debate as to which approach is “best”.
Let’s start with the older technology, XML. Few people would argue against the fact that XML is strictly structured and highly standardized. Thanks to this, there is only one way of writing something in XML. This actually makes it very easy parseable and interpretable by automatic tools; there is no need to write some special software for this, and there are a lot of them already that handle it pretty well.
DSL, on the other hand, focuses on a high level of customization. You don’t have to write plugins or obscure bunches of XML, instead you write stuff right inside the script. Also, DSL is less verbose and closer to the problem domain. Of course it has much less boilerplate, the issue that XML often takes heat over, and this results DSL being able to accomplish the same thing with less typing and better readability. These advantages however come at a cost: it’s harder to implement a DSL interpreter.
How do these properties apply to Maven, Gradle and Ant? Well, we think that the easiest build script to read for a complete n00b is with Ant. Its XML is well-structured and being verbose in this case is more a plus than a minus. In a way, Maven’s disadvantage compared to Ant is that it is based on certain conventions that are written outside of the build script and one should familiarize themselves with those before reading pom.xml. Maven is more focused on dependency management and doesn’t allow developers to create complex, customized build scripts very easily.
When it comes to Gradle, an uninitiated developer might see it as a mystery wrapped in an enigma. Imagine seeing a build script that contains just this one line:
apply plugin: 'java'
Without any further information, Gradle will magically add some tasks to the project. So programmers that are not familiar with Gradle at all must go through the documentation before they can even read the build script! But this obstruction comes through with a pot of gold at the end: though Gradle is the most difficult to get started with right away, you’ll get much more power over your build scripts, since it allows you to more or less write Groovy code (not too far away from Java) directly inside them.
But in the end it all comes to personal preference. There are people who swear by XML, while others accept nothing but Rake (Ruby’s version of the classic tool Make). Over the next month or so, we’ll be releasing a couple more posts and a report we that will help you choose your “build tool for life” so that your own preferences can be based on something better than just a gut feeling.
So that’s that–but wait, you’re thinking–aren’t you going to talk about dependency management? It turns out we accidently kept that in the title when the topic was already ported to a later blog post here:
Stay tuned for more…and please tweet @RebelLabs or leave comments below to get the discussion started!