Posted on Dec 31, 2010 by

Build and Release Management With Apache Maven

More than ten years ago, Joel Spolsky of "Joel on Software" fame wrote The Joel Test: 12 Steps to Better Code. It was a great set of 12 yes/no questions, all of which you should be able to honestly answer "yes" if your team is to have any hope of producing good software in a timely and efficient manner.

The Joel Test stands up pretty well even today. Joel's first two questions, "Do you use source control?" and "Can you make a build in one step?" are a good start at addressing the need for build automation. With the tools available today, however, I suggest that build management (not just automation) and release management should be added to the "must have" list for productive software development teams.

Since I mostly work in Java, I'll talk about Java build and release management. There are a few comprehensive tools for Java build and release management (actually many more build management tools than release management tools), but the most popular by far is Apache Maven.

Maven started in 2001 as a part of the Apache Alexandria project, moved to be a part of the Apache Turbine project in 2002, became a top-level Apache project in 2003, and had its first milestone release, v1.0, in October of 2005. Version 2.2.1 has been in wide use since its release in August of 2009. Version 3.0 was released in October of 2010, and the current version, 3.0.1 was released in November 2010.

Maven bills itself as a "software project management and comprehension tool". Its most basic use is as a build tool, commonly as a replacement for Apache Ant, but it does several other things, which taken together, really do form a useful software project management and comprehension tool. Maven is certainly not an absolute requirement for a good software development team, but the issues that it addresses must be addressed somehow. If your Java development team is not currently addressing these issues in a satisfactory way now, Maven is a good way to get started addressing them in a coherent way.

As a build tool, Maven takes the now-common "convention over configuration" approach that seems to have started around 2004 with the Ruby on Rails web framework. As such, Maven was designed to be a highly opinionated tool, giving structure to the free-for-all that Ant usage had become in many projects. Maven is based on the Project Object Model, an XML configuration file that specifies what goes into a project, but unlike Ant, generally not how to build it. This is where the convention over configuration comes in - you put your source code and other build artifacts in a directory structure that Maven expects, and then Maven can build it with no further configuration. This results in both simplified build management (no build script to write and maintain), and a project that anyone familiar with Maven can build. There is a well-defined build lifecycle, with well-defined targets: "mvn install" builds, tests, and packages any project built with Maven, and installs the resulting artifact in a local repository (more about repositories later). This is a great improvement over Ant, where the names of the build targets, and what they do are up to the whim of the person writing the Ant build script.

>Maven is much more than just a build tool. It has many more features, but to me, the most important are Dependency Management and Release Management.

Dependency Management is all about dealing with the libraries (jar files) upon which your project depends (direct dependencies), and those jar files' dependencies (transitive dependencies). With Ant or any other build system that does not manage dependencies, this is left as a manual exercise for the developers. Typically, all of the dependencies are resolved manually, and all of the jar files are put into the project's 'lib' directory. This frequently means that multiple projects using the same third-party libraries will each need to keep a copy of them.

Maven's paradigm is to have the developer declare the project's direct dependencies in the POM. Maven then resolves the transitive dependencies, and pulls the required jar files (direct and transitive dependencies) from a Maven Repository at build time. Jar files are not kept within the project, just the specification of which jar files to use at build time. There is a "standard" external repository (the "central" repository) that is web-based, and hosted by maven.org, and a local repository in the filesystem on the developer's machine. Jar files are pulled from the central repository, or other external repositories that may be configured, and cached in the local repository.

This arrangement works well for small, one-off development efforts, but many shops have reusable jar files of their own that are used by multiple internal projects. Historically, many development teams have distributed these reusable in-house developed jar files by either putting them on a shared network directory, or by checking them into the source code version control system. This results in a process that is more manual and cumbersome than it should be, and generally violates the DRY principle.

Using Maven instead of Ant or a home-grown build system, and managing dependencies through it are a good first step, but for reusable code, Release Management becomes important, and again, Maven can help. Maven, through its release plugin, supports a well-defined release lifecycle, and allows teams to store their reusable code in a centralized Maven repository, just like the "standard" jar files that are kept in the central repository. Teams (or whole companies) can set up their own internal, web-based repository that either enhances or replaces the central repository. Using Maven, they can then "release" their jar files to this repository. Projects using Maven can then declare these jar files as dependencies the same way that they do for jar files in the central repository, and they will be resolved by Maven. No need for shared directories, or placing binaries in the source code version control system. The release plugin takes care of incrementing version numbers and updating them in the version control system, in a standard way.

The features that have been presented here are just the most prominent ones - Maven is capable of much more, especially with its extensive list of plugins. If your team is not using Maven (or something like it), or is only using Maven as a build tool, I encourage you to spend some time learning more about Maven. It will be time well spent. There are the Maven project's own "Getting Started" guides and a series of books by Sonatype (the commercial company behind Maven) for starters.

Sonatype provides online, instructor-led training courses, and here at Chariot Solutions, we offer public, on-site training in our Ft. Washington, PA facility, as well as custom private courses.