20070826

Maven (non)-bashing

Looks like the popular sport of bashing Maven continues. Just thought I'd add my own opinion to the mix.

Background

At work, I've instated Maven use for new projects as well as some active projects (those I could get people to migrate, anyhow) about nine months ago. My reasons were the following:

  1. We had a crufty Ant-based build system (which I built myself, I'm ashamed to say--I think my only excuse is that it replaced another, cruftier Ant-based build system with really wonked dependency management), and some of its persistent bugs (wonked version number handling and unversioned third party libraries) were really starting to get on my nerve and other developers';
  2. I'd tried out Ivy, and I had problems getting it to just work (this was way before the current version, at a time the documentation was rather sparse);
  3. A co-worker started bugging me about "why not Maven," so I got curious;
  4. I finally found out how to adapt the pom.xml file to a non-standard directory structure, from the Wicket project's pom files. This was the clincher, because I really hated the standard Maven layout (especially separated code and resources directories--ugh) and I wanted to be able to retrofit our old projects that had a more widespread layout (source in src/, tests in test/ and webapp in www/).

Initially, I was the only Maven user in the whole place. I introduced my team mate who worked on the same project I was doing, and more recently, I ported a whole bunch of legacy stuff to use Maven instead of the old script, declaring that if that stuff could be ported, anything could. Two other co-workers started using the Maven build at that time, and so far, they feel it's been positive.

Maven bashing

OK, fasten your seat belts, folks, because that's going to hurt.

I had two huge problems with Maven:

  • Bugs
  • Very, very generic documentation for many non-generic tasks, like sofware release (mvn release:prepare and mvn release:perform)

The main bugs I hit were huge bugs with the CVS SCM provider that made the release plugin basically unusable. I tried fixing it myself, but I nearly burned my eyes out navigating the SCM module source code. This is another sub-complaint: the code quality is, frankly, not that amazing. It's a bunch of too-small modules strewn together, and sometimes the modularization is pushed a bit too far for my tastes: you get a package with interfaces only, a package with the implementation, a package with just the model created automatically from modello files, and then a package for each different plug-in. That's two extra packages, in my view, and it means a very high cognitive load.

The main problem with the documentation was that it was highly variable. Sometimes, you get amazing details, lots of examples. Sometimes, you get a glib description and the goal documentation (note to plug-in developers: the goal documentation would be much better if the configuration parameters were actually explained; sometimes, it's not clear exactly what a term means in a given context, and being told "localRepository: local repository path" does not help much). Sometimes, you only get autogenerated stuff with no description whatsoever.

Also, I wish more attention were paid to error messages. This is a common problem in software, however; Maven is not the only (nor necessarily the worse) culprit. Exception: the archetype plugin is one of the stupidest thing I've seen from an error-reporting point of view. When it's missing files, it just throws "unable to copy file" without having the decency to tell you which one... even the stack trace is mum about this.

Maven praises

However, I'm not convinced that this is an excuse to ditch the whole system. The main concepts, if not necessarily the code, are quite solid. I wish there was a way to specify ordering when binding many plug-ins to a single phase, but that's the kind of stuff that's not needed that often.

Maven works mostly as documented, and when it works, it works really, really well. In my experience, it's relatively speedy (at least, compared to my hokey ant script). The release plugin, now that they fixed many, many bugs with CVS interaction (actually, the CVS plugin may have been the culprit, I was never able to ascertain this because the code was really "indirect" about it), works beautifully.

Writing a plug-in is really easy. Even compared with Ant tasks. Yes, it's that easy. It's a shame some Plexus or Maven core stuff is so poorly documented, but you can usually figure it out by looking at a similar plug-in.

Despite what a lot of people say, it is very much possible to have Maven work outside its standards. You'll have to be more verbose in your pom.xml, or use a parent pom. Wicket, as well as our own projects, are testaments to this flexibility. You have to hunt around for information on how to do this, but it is available on the Maven site.

Conclusion

Despite some shortcomings, I truly believe Maven is a very good build system. It was maybe a bit too ambitious at first, but since 2.0.5, it started being able to deliver on those ambitions. It is also much more flexible than people give it credit for.

For those banging their heads with it, I advise that you look at the Wicket and AppFuse pom.xml files. Likely they've solved your problems already, so you can just stealborrow their solution. :-)

20070810

Assertions in Eclipse

A small trick I found. While running unit tests, I realized that the Maven Surefire plug-in enables assertions during the test run, while Eclipse does not do so (at least, not by default). Looking for a way to enable assertions at unit test time, I found that you can go to Windows | Preferences... > Java | JUnit and select the "Enable assertions for new JUnit launch configurations" checkbox. Hope this helps somebody somehow.