maven in anger

I’ve ranted about Maven before. As it happens, I still stand by much of what I said. But, I’ve come to realise how superficial these criticisms are.

Earlier this year, one of the libraries that I have a hand in maintaining needed to be used by a maven project. Whilst I could have just written enough of a POM to specify my dependencies, I figured that it would probably be easier to just switch the build system to maven.

Plus, this particular library is meant to be used as a webapp. The existing ant build builds a war file. But really, the webapp is just for exercising the library, it’s not the main point. Switching to maven makes it ideal for splitting into two different projects.

So I went ahead, and made the change. I did it in a slightly invasive manner (moving my source directories around to fit the expectations of maven). But the end result is that I have found the project easier to work with. Previously, the dependencies of the project were very unclear. Switching to maven and running mvn dependency:analyze quickly spotted quite a few jar files we “depended” on weren’t actually used. And one of the nice things is that maven embeds the version number1 in the resulting jars (previously it had been a chore to figure out what version was in use).

This turned out reasonably well, although the main benefits were yet to be had. These are down to the huge growth in the maven tooling ecosystem, particularly this year.

  • Eclipse support has been improving by leaps and bounds. Initially I went with q4e (now IAM), but I later switched to m2eclipse as it seems to be a more fully-featured plugin right now.
  • NetBeans has pretty good maven support, even though it’s lacking a couple of useful features in m2eclipse. But it’s also very nice as NetBeans is then entirely driven by the POM — it doesn’t create a bunch of files based on the POM. The POM is the project.
  • Hudson makes it an absolute snap to get a maven project into continuous integration. Hudson is the only java project I’ve ever seen that comes close to the simplicity of a wordpress install. Way to go Kohsuke!
  • The nexus repository manager makes using maven much more practical (even for a single developer) as it vastly speeds up downloads and reduces your dependency on central. Plus, you can use it as a place to deploy your own goodies once you’ve built them.
  • Maven: The definitive guide — the maven documentation, whilst there’s a good deal of it, isn’t exactly integrated well. This book has been an enormous eye opener about how to do things “the maven way.” Plus the in-depth coverage of things like the assembly plugin was tremendously helpful.

With all these tools in place you find the integration really starts to come to the fore. For example, I noticed that hudson had a findbugs plugin. I installed the plugin in hudson, activated the findbugs plugin in my POM (about 4 lines of XML) and got:

  • Pretty graphs of the number of bugs found in each build.
    findbugs-trend.png
  • Detailed breakdown of each findbugs report in each build, including source code views of where the problems lie.

    hudson-findbugs-fixed.png

  • Indicators showing how many bugs I had introduced into each build (or hopefully removed).
    hudson-findbugs-warn.png

In short, I got a lot of value out of a (relatively) small change. And the same technique can be applied almost identically on the next maven project. And the one after that. And so on. Consistency has been one of the great virtues of maven for us.

The end result is that now most of our projects are maven projects at work (and I’m also using maven at home).

Of course, it’s not all plain sailing. I’m still seeing something weird to do with m2eclipse and WTP. But I’m confident that I’ll figure it out and it’ll be fixed.

Overall, I reckon that maven is something you should be taking a look at if you’re building Java projects. I know some people had taken a look at Maven 1 and come away with a sour taste. Now’s the time to check back and see what’s changed.

1 Even though I later had to change how this was done.