Wednesday, 13 May 2015

Maven and Me

I've had it with Maven.  I've been using it for years and it just doesn't seem to get any better.  Faster, perhaps, but understandable - not.  It works out-of-the-box for small single jar or war projects.  However, to me there seems to be no rhyme or reason why certain combinations of config work and others don't.  Generally, if you get something working (however inefficiently), it is best to leave it alone.  Going beyond the narrow functionality that came out-of-the-box, is likely to waste you a lot of time and not achieve what you needed anyway.

Unfortunately using Maven to build multiple projects is really beyond that out-of-the-box functionality.

The perennial problem is shared plugin configuration. With maven you have two options:
  • Repeat everything everywhere.
  • Configure a plugin in a parent pom and inherit that configuration throughout all your projects.

The chances are that not all your projects are the same.  Tough.  If you want to use a plugin with some shared config in 2 places, but another shared config in a third and fourth, then you are going to be unlucky.  You are going to spend a lot of time on Stackoverflow, getting short shift from people who (at best) will tell that you shouldn't be trying to do that.  The best you can do is share one set of config in some places, and not use the plugin at all anywhere else.

There are some tricks.
  • You can bind the other set of plugin config to a different phase using executions.  This depends upon there being a different phase that you can use - this is very limited and your project will probably be too big.  It would have been nice if you could specify the id of the execution you want to use.  (I don't understand what else the id could be for, but apparently it's not for this. Some say it does do this, but then some people like to waste your time.  Also ignore people who suggest using profiles - profiles are applied equally to all projects).
  • Local project properties. If you have just one or two differences in a larger set of config, then you can make the config reference a property and set those properties locally in all the projects that you use the plugin.  (It is a shame that you can't trigger a different profile using a local property).

Parent POMS

Maven also has a problem with what is means by a parent POM (which it inherits config from) and a super/multi-module/aggregator POM.  Some of the documentation tries to draw a distinction, but then shows examples where the two are lumped together in one file.  This is odd, as the parent must be built first and put into your repo before all the projects that use it.  A multi-module POM is put into the repo last.  If you use a single POM for both, and clear out of your repo, or checkout and build a single project, then you get a cyclic dependency.  You can get around it by "fixing" your parent/multi-module POM to remove references to the sub-projects, "unfixing" it once it is in the repo, then re-building.

Obviously you should use two different POMs, but it is not clear how this should be done.  I even think the Maven developers aren't clear on this.  Those developers that use Eclipse have always put the parent POM in a sibling project (because in the past Eclipse didn't like nested projects).  If we do the same, should we then name this parent project in the list of modules?  In Maven 3 the enforcer plugin's Reactor Module Convergence rule complains if the parent is not within the list of modules, but if you put it in it then complains that there is POM without a parent (i.e. the parent POM itself).

When Ant first came out, I was frustrated at how verbose and limited it was compared to Make.  I take it all back.

No comments:

Post a Comment