Response to Maven Problems on the JBoss Wiki, Part Two


December 3, 2009 By Brian Fox

In part one of this series, I addressed several concerns raised on the a Jboss wiki. In this post, I specifically focus on the issues raised with the release plugin.

The wiki states:

The release process is not reliable Maven projects use the maven release plugin to help automate the release. Unfortunately we have experienced numerous problems with this plugin. The problem is not so much the bugs in the plugin….I think a lot of the problems with the release plugin stem from two things…

Before we dive in further, the idea behind the release plugin is that most releases follow these general steps:

  1. Build and verify that the tests pass
  2. Tag it
  3. Checkout and build the tag to be sure what you tagged is in fact correct
  4. Publish the artifacts of the build for testing

The release plugin handles steps 1 and 2 in the release:prepare goal. Steps 3 and 4 are done by release:perform.

Maven’s normal development process adds a few extra steps in there regarding the conversion of the versions from SNAPSHOTS to releases, but the above steps are generally what is being automated.

In addition to automating the testing and tagging process, the plugin also makes sure you don’t:

  • have uncommitted changes
  • depend on any snapshots

It’s worth noting here that there is no requirement to use the release plugin. It’s meant to encapsulate best practices and generally make life easier for maven projects, but if it doesn’t, don’t use it. It’s a plugin and the logic isn’t baked into Maven core.

One is the svn tag and checkout. Because these are not done prior to the start of the release process, if there are any problems with these steps they will block a release. They can be difficult to debug because the release plugin forces the whole process to restart in order to solve the issue. Manually doing a tag and checkout is much easier because issues with svn can be resolved by themselves outside of the release plugin automation process.

If you were to manually tag and checkout something, I presume you would have built it first to make sure your tests pass? You’re asking the release plugin to pickup at step 3 above and let you do steps 1 and 2 manually, at that point you might as well not even use the release plugin and just run ‘mvn deploy’.

The release plugin has a state machine that keeps track of the last step that successfully passed. This means it doesn’t require you to start back at the beginning if something fails during the prepare process. It is true that if errors are encountered during perform that require changing code, you will have to redo the tags. There is a rollback goal to handle this.

The second major issue comes from changing the version numbers in the pom at release time. The POM versions are changed automatically by the release plugin. This seems like a good thing at first, but it can cause unforseen problems in multimodule projects that need to resolve inter-module dependencies. Sometimes dependency resolution errors are found only at release time because the new versions do not yet exist in the maven repository. This is another area where a more manual process would be preferred in many cases because the multiple step nature of the release plugin can make debugging difficult and time consuming.

The changing of the version numbers isn’t directly the problem here but it is a trigger. There are some weird interactions with some plugins and the reactor that can cause them to not resolve things that aren’t in the local repository. This has been significantly improved in Maven 3.x but it’s impossible to say if all plugins will work correctly yet. Some, like the dependency plugin may need updates to find things in the reactor.

Generally speaking though, it is possible to make your build behave correctly in a perfect clean-room scenario (i.e. where no snapshots of this project exist yet), and if it does that, releasing won’t be a problem. If it doesn’t, that’s an indicator that the build might need a few tweaks.

For all maven projects I currently work on at Sonatype and at Apache, the release plugin works perfectly. The key to this is that most of these projects were setup originally as Maven2 projects and thus follow all the best practices.

However

That said, I’m also not a huge fan of the current release plugin and have had troubles with it on other projects, so I totally sympathize. My main beef is that while the steps in the release plugin are appropriate for most projects, sometimes they just don’t fit yours.

I would like to see the release process become more like a lifecycle, and each individual action bound like a plugin to a phase. Then you can totally rewire the steps in the order that makes most sense for your project.

I have built the equivalent of the release steps as enforcer goals over the years working in the direction of a pluggable release lifecycle. It is possible today with the enforcer to string together all the validations into your own release process, completely bypassing the release plugin all together. That leaves you to manually tag, checkout and manipulate the versions, but sometimes that’s just what you need/want to do.

All that’s needed is someone to put the time in to create this new release plugin.

Part 3 will address the rest of the issues raised.