Fear, Magic, and Maven

Posted On // Leave a Comment
For the longest time, I was an Ant bigot.

Before Ant, builds in Java were either all manual calls to javac, perhaps shell scripts if you were lucky, or done via some IDE magic for you. Ant, like the venerable GNU make and other tools before it, helped provide an automated, repeatable way to build and assemble complex projects. Write a little XML file with the steps for your process, and then a simple call to "ant" would start things happening. Ant was a god-send in large projects since it could eventually handle everything from generating source code all the way to deploying your project to a server. No more builds by hand! So why would anyone go to any other tool?

Well, putting together Ant scripts slowly became a development effort unto themselves. The scripts themselves got more and more complex. You had to start downloading extra jars to extend the functionality of Ant (although the Ant team very quickly rectified this by bundling up the most popular plug-ins into the project). Also, with the explosion of OSS, projects were beginning to pull in more and more frameworks, utilities, and other Java code to make the development effort easier. These frameworks might need other frameworks and utilities themselves, and sometimes certain common frameworks (Apache Commons for one) would be needed by multiple JARs. The problem really started to become an issue when certain libraries needed certain versions of a common framework, and other libraries needed a different version.

Ant (until the addition of some other tools such as Ivy) really didn't have a way to help manage all those dependencies. This was just something that you had to do by hand to set up a project. Download a bunch of files, get them on the class path for your project, and then write some small tests to make sure everything was working properly. Later on, adding in a library could cause a whole chain of problems in components that were working just fine before simply because the new library loaded some newer versions of classes from a common library.

When I first heard about Maven, I really didn't understand why we needed "another Ant." OK, so Maven could do builds, but Ant had been doing them just fine for years, thank you very much. So I sat in blissful ignorance for quite some time.

Eventually there came a time that I wanted to use an OSS project that needed to be built. It just so happened that that particular project chose to use maven for their build. I actually was kinda pissed that I had to download another tool to build with, but I did it.

After building, I decided to take a look at this strange pom.xml (Maven 2 had just been released at the time). I opened up the file with my multifaceted Ant eyes fully expecting to be able to see the steps in the in the build process. Imagine my shock when all I saw was some basic info about the project and some "dependency" tags.

I remember thinking, "Where is the compile target?" I thought I must have looked in the wrong file, so I started looking around in the project to find the "real" build script.

Nothing. Nada. Zip. Zero.

I left it as a future task to figure out this crazy maven thing and why people were using it.

I've learned a lot more about Maven since that point (and there is still a _lot_ more for me to learn!), but a situation in my current job with an ISV around whether or not we should go with Maven or some other tool made me think back to the uneasy fear I had about this insane build tool with no targets. Uncertainty = Fear, and fear drives many (if not all) of the decisions people make.

With Ant, most everything was clearly defined, and you could actually walk through a simple Ant build script and mostly understand what was going on. Maven has a philosophy of intelligent defaults for all the steps in a build process. This means that a build configuration can be quite sparse, and only contain the things that need to change. The side effect of this design choice is that much of the hard work is hidden from casual view. You can write a few lines of XML, and then mutter an arcane incantation in the shell to compile, test, package and build a website for your project.

Reading some of the above text, you might think that I don't like Maven. Actually, I love the dependency management, filtering, and archetypes features quite a bit. I just had (and continue to have to) overcome my initial fear of Maven.

Part of the problem may also be that most of the really cool feature documentation is spread out amongst the various plug-ins to Maven. This makes it a bit harder to find, and hinders learning. If this could be rectified (and maybe it is is some great Maven book that I just haven't looked for yet), then I would imagine adoption would skyrocket.

So, my team is currently on the fence between Maven, or moving to another tool. We'll see what happens.