Java projects need a way to produce binaries from sources. There are many tools out there that can achieve this goal, Apache Maven has been so far the most popular choice, chances are you have encountered in one way or another. Maven as we know it today is the result of a couple of iterations, starting with Maven 1 where the build was one step removed from its predecessor tool: Apache Ant. Maven 1 gave you a lot of freedom to define how a particular build should behave but forced developers to use XML in a programmatic way. This lead to lots of problems and a lot of pain.
Maven 2 learned its lessons and removed the scripting capabilities by pushing custom behavior to Java based plugins. You’re still able to define build settings and configuration in a declarative way, using an XML based DSL. As time passed by projects grew in complexity and the need to build multiple modules as part of the same project surfaced, as a result the project reactor came to be and the popularity of Maven kept growing. The reactor was added as part of core features of Maven 3, as well as a few other features.
Starting with Maven is quite simple, you simply need to download a copy of the software (usually from project’s download page) and follow the install instructions. It’s also possible to use package managers (such as Brew or Macports on OSX, apt-get on Debian based Linux distros, etc) to install Maven on your system. Once installed you may run mvn --version to verify that the tool has been installed correctly; this is how it looks on my laptop at the time of posting this entry
$ mvn --version Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-03T21:39:06+02:00) Maven home: /Users/aalmiray/.sdkman/candidates/maven/current Java version: 1.8.0_131, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre Default locale: en_US, platform encoding: UTF-8 OS name: "mac os x", version: "10.12.5", arch: "x86_64", family: "mac"
Let me point out that the tool writes out the timestamp and commit hash at the time of its release, which is very useful if you ever encounter a problem when using the tool. Remind yourself to include this information when submitting an issue and/or discussing the problem with your peers. Next up would be setting up the build file and the project structure, for which there are many ways to do it depending on your IDE/editing tool of choice. The Maven website provides useful hints on how to accomplish this feat which I won’t repeat here for brevity.
Maven has been widely adopted around the globe; there are plenty of places where you can find information on how to configure it for a particular task. While it’s rather easy to get started my personal preference is to use a different build tool due to the following reasons:
- Maven’s build lifecycle is too constrained and can’t be adapted to the needs of a particular project. It works great for single module projects and web application projects. The cracks begin to appear the moment the project requires custom behavior. Of course Maven is extensible via plugins, and it’s likely that you may find a plugin that delivers most of the features you may need. However if that’s not the case then your next option is to create a plugin of your own, and that is not an easy task in my personal experience. Your mileage may vary.
- Maven requires all artifacts to reside in a repository in order to resolve them as dependencies. This includes local artifacts produced in a multi module setup. Looking at the official documentation we find that the suggested way to use Maven is to invoke mvn install, which builds the project and pushes the binaries and their metadata to a local artifact repository commonly known as Maven Local, available only in the machine where the build was made. This poses the problem of having to constantly refresh the local repository with the latest binaries or risk the chance of consuming an outdated dependency; this happens more often than you think.
- Maven’s build file (pom.xml) defines how the project should be built as well as the metadata required by consumer projects. This means pom files may grow big and some private or unneeded details have to be published. It’s my opinion that it would be better if just the recipe for consuming the project were to be published.
Despite this, Maven’s strict rules (or inflexibility as other put it) is seen as a good thing by many as they regard the tool as a gatekeeper (or babysitter), disallowing developers from going crazy with a build file. My experience across the years has been the following: the question is not IF you need the tool to be flexible but rather WHEN. If you’re starting a new project I’d recommend to pick a different build tool (such as Gradle, discussed on the next post) that grants you the flexibility when you need it yet adheres to conventions just like Maven does.