The Blog

Sep 9, 2007

Build Tools: Maven 2 

by Maxim Porges @ 12:09 AM | Link | Feedback (2)

I'm evaluating Maven 2 as a build tool for our environment. Here are my findings so far.

Adam had been assigned the task of doing a high level evaluation of Maven 2 for us, and wrote a page on our internal Wiki on his findings. I was really intrigued by Adam's evaluation, and decided to play around with Maven to see if it really was as convoluted and error-prone as some of the other build solution communities had lead us to believe. I was also interested in why the guys at the Apache group would use this tool regularly if it was so troublesome, especially when they had created it to simplify and empower their Ant-based builds - exactly the reason we were looking for new tools ourselves.

Giving Maven a Chance
I had looked in to Maven in the past (over a year ago) and found the documentation painfully lacking. On this, my second tour, I found Apache's Maven 2 web site very useful with quick start guides and comprehensive examples and documentation for the wide array of pre-existing plugins available. I did have to do some digging on Google for some specifics and examples, and found some of the build files in public SVN repositories useful for the less-well-documented plugins. I also found the book Better Builds with Maven extremely useful, even though it requires you to sign up to download it, and you can't copy/paste text out of it for some strange reason (I've only worked with it on the Mac so this might not be an issue on Windows or Linux).

I've probably sunk a sum total of 8-10 hours in to learning Maven and putting together my POC build, and I'm somewhat surprised to say it's doing just about everything I need it to, and did so the first time around with no issues. I've got objectives #1, #2, and #3 from the bottom of my previous blog post on the topic nailed, with a few bells and whistles on top.

With regard to objective #3 (generate documentation), Maven spoils the user for choice. There are 11 reporting/code quality plugins listed in Better Builds with Maven, handling everything from code quality/standards enforcement, to copy/paste detection, to todo listing, to test coverage/result reporting, to change logging. Maven builds JavaDocs out of the box, and allows you to easily link to standard JavaDoc documents such as those from Sun for Java and JEE. Maven also has the built in ability to generate a documentation web site, which you can customize through creating templates utilizing a simple markup language, and then publish to the server of your choice using a variety of methods including FTP, HTTP, and several others.

Today, I leveraged Maven's inheritance model to set up a common build file that will work for all of our Java-based projects, requiring almost no configuration by developers as they start new projects. Here's a sample of the XML file a developer would have to write to build any of our Java projects:

<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.westgateresorts</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>sample-maven-project</artifactId>
<name>subproject</name>
<packaging>jar</packaging>
</project>


With the exception of following a very simple pattern for indicating project dependencies, that's the entire file. Without expecting you to understand Maven 2's POM files, this block of XML simply defines the parent config file, the name of the component for the project being described, and that the project should be packaged as a JAR file. Besides this boilerplate block, the developer requires no knowledge of Maven unless they need to customize the build. This should be a non-issue in 95% of cases since all of our Java apps follow a similar convention and are (at present) either JAR'd as a library or wrapped in servlet-based application (both of which Maven supports out of the box). If we need to accommodate different builds in the future, pretty much all the changes can be encapsulated in the parent build file, removing the need to edit the individual build files as much as possible.

Also note that this same build file inherits the ability to bootstrap an Eclipse project for the developer, allowing almost instantaneous access to a working project for them to get to work on.

Maven has the ability to customize builds to differing profiles, and to store server access information in a settings file in the user's home directory. Combing these features with an Artifactory repository and SVN server, it was a snap to set Maven up to build differently for varying environments. Essentially, each role in our development lifecycle (developer, QA analyst, buildmaster) would have an appropriately configured settings file, and that would take care of indicating what sort of build should be run, including customized deployment options and the addition and removal of custom steps. Artifactory also allows restricted read/write/delete access to repositories, so we can lock down who can publish builds and to where, allowing us to enforce process and responsibilities in to our build lifecycle.

Migration
As it turns out, migrating from our Ant-based builds would be a snap.

1) Two directories full of existing code would need to be moved to new locations meeting Maven's conventions.

2) Two new directories would need to be created and populated with production and QA resource files.

3) A pom.xml file very similar to the code sample listed above would need to be added to the project directory.

4) Any customizations would need to be added to the pom.xml file.

For all the projects I have worked on so far, the only item I can see potentially needing tweaking in the project's pom.xml file is the target Java version, which is a simple addition to the <builds/> area of the POM file.

Favorite Features So Far
- Being able to inherit from a standard build file that can be easily distributed as our process changes.
- Loads of plugins, all of which (so far) worked right out of the box.
- Lots of documentation online and sample applications.
- Good choices for Maven project conventions, which would make sense to our developers.
- Ability to modularize larger projects, providing additional convenience through the inheritance model.
- The build goals that Maven follows meet best practices for software development out of the box.
- Abstraction over our source control implementation. With a little more work I'll have the builds able to branch/tag code, and auto-increment version numbers too.
- Tight integration with Artifactory, which has been a pleasure to use and configure.
- Archetypes can be created as project templates, so that developers can start new Maven projects using the customized template for our environment that I have created.
- There's a pretty nice Eclipse plugin for Maven that hooks in to Eclipse's build process and really makes the build and dependency resolution seamless to the developer.

Unexplored Options and Gotchas
- I haven't looked at scripting at all yet. I have a feeling that this will be a major weakness for Maven, considering that it is XML-based and plugins must be written in Java.
- The learning curve for Artifactory and Maven together wasn't too steep for me personally, but wasn't short either.
- There's a Flex plugin out there, but I have yet to use it. Adam said it worked fine, but I need to validate that.
- There's nothing by way of a plugin for ColdFusion yet; we'll have to write our own or script something. Again, I see this being more complex for Maven than for Buildr. That being said, this would be a one-time task that I doubt would change much after it was completed.
- I haven't tackled deployment to production or post-deployment scripting. To be honest, at the present time I could easily see us doing builds with Maven and deployments with a scripting language such as Ruby or Python. But if you're going to jump in to Ruby, you might as well just use Buildr for the whole thing, which gives me yet another reason to investigate Buildr as an alternative.

On to Buildr
I've gotten the impression from Dan that Buildr basically does all the same stuff as Maven but with a hell of a lot less effort. That being said, we've already identified that the SVN integration isn't as immediate as it is with Maven, and I'll be surprised if Buildr's documentation options are as comprehensive out of the box.

However, I'm open minded to what Buildr offers over Maven, specifically Ruby scripting (which should hopefully make the missing SVN integration almost a non-issue, since we can invoke the command line from Ruby). I'm also hoping for a more pragmatic approach to builds, considering Buildr was introduced by a team of people trying to make what is essentially a simpler and better version of Maven.

Dan and I are getting together next week to look at my Maven POC and see what sort of effort it is to implement the same thing in Buildr. I'd love nothing more than to get the same benefits I've found with Maven with a terser build language, and what is hopefully a shorter learning curve to boot.