Maven is a build management system that emphasizes convention over configuration. This means that working with Maven requires you to structure your source code hierarchy in a very specific way. I was put off for a while with all the demands Maven made about how I do things but after working with Maven for a month now the light has finally gone on for me about where Maven brings value to our build process that Ant couldn’t match.
The advantage Maven offers over Ant is the emphasis on convention allows for the implementation of an inheritance hierarchy of Project Object Model files to provide a flow of behavior across a tree of related projects. Each Maven project defines a pom.xml file that specifies the behavior for that project. Behavior means how the project is built, packaged, and deployed. In addition, the pom.xml is where one specifies the dependencies for the project and additionally, execution of the various activities can be customized in the pom as well. The dependency specification mechanism employs the notion of a shared hierarchy of Maven repositories from which jar files are automatically downloaded if they’re not found locally. Moreover, without much effort our local repository (Archiva on Tomcat) was configured to be updated when a jar file was downloaded from the Maven central repository so the next time that dependency is required it is found locally.
This is by no means a trivial amount of work but it really pays off as projects grow. Each sub-project specifies a parent pom.xml file and inherits all of the behavior and properties of the parent. In this way, just like in coding using inheritance, the only behaviors that I need to add or change in the child are the ones that differ from the parent. Of course, some of this can be done in Ant as well through includes of a build file or the referencing of a properties file but the semantics of Ant just don’t match up to the relationships as intuitively to me. With Maven, you have to be clear about how sub-projects relate to their parent in order to use the tool effectively. This in turn forces one to be precise about the relationships between projects.
Projects can specify their relationships to sub-projects as either dependencies or as “module sets”. Module sets made sense to us at first but we’ve learned recently that by making everything dependencies we can actually reduce the amount of code that needs to be checked out. If I’m working on code that has dependencies on libraries built from several other projects, because they’re dependencies, the jar files will be automatically downloaded by Maven. This means that I have less set up to do when I go to work in a particular area of code. Of course, this doesn’t replacing updating from source control and running a clean build to ensure I haven’t broken other areas but it does mean that I can get to work more quickly.
Pom projects are folders that contain just a pom.xml file and no code. These projects are used to organize sub-proejcts (module). The benefit is that when I’m in one of these projects and I invoke ‘mvn clean deploy’ – all of the specified modules will be built and deployed too. Yes, one can do this with a hierarchy of Ant build scripts but since I’ve used both now, I’m very convinced that how modules relate and interact is much clearer to understand in a pom hierarchy than in an equivalent set of Ant build scripts. The other part of the Maven solution that I believe is superior to Ant is that all the behavior executed by Maven is defined in plugins that are downloaded from the central Maven repository as well. This may seem unintuitive at first – why would I want my tools definitions to be abstracted in such a way? The answer is that the various plugins available in your build are being expanded upon and improved by others so that when you run a compile or deploy task, you dynamically can get the latest version of the plugin and new Maven behaviors become available simply by defining them in the pom.xml. Of course, like with dependencies, you can specify a version too so that you can use an earlier implementation if you prefer to do so.
In summary, I’m really sold on Maven. It is making our build-deploy system more comprehensible and flexible. I’m not asserting that it is always advised to scrap a solid, functioning, Ant run system for Maven but if you’re reaching the limits of what Ant can do for you (a sure sign is lots of programmatic type features in your build.xml) Maven is certainly worth evaluating. Maven also plugs into the Hudson build management system which I recommend highly too.