Cutting a Release of a Maven Project

Introduction

As more of our projects becomes inter-related, it becomes more important to consider the dynamics of releasing these projects.

For example, on a recent project we dropped a release to the customer without bothering to cut revisions of the Intelliware projects that we depend on. When we needed to do maintenance on that branch, it was unnecessarily difficult since the SNAPSHOT revision that we depended on had evolved and our branch no longer compiled.

To avoid this, we should have cut releases of the dependent projects. We could have gone a step further and cut a real release of our project as well.

The Maven release plugin

In theory, creating a release is easy. Just use the Maven Release Plugin.

mvn release:prepare

followed by

mvn release:perform

In case there’s a problem,

mvn release:rollback

will return your project to its pre-release state.

You can also run a “dryRun” to test the release:prepare stage if you want

mvn -DdryRun=true release:prepare

If all is well then just run clean before you do the true release:prepare

mvn release:clean

The plugin does everything that you need:

  1. updates the version of your project by removing the -SNAPSHOT designation. For example, 1.2-SNAPSHOT will be updated to 1.2.
  2. tags the release in svn as projectname-1.2.
  3. deploys the updated project to the repository
  4. again updates the version of your project to the next SNAPSHOT revision. To continue the example above, the project would now be at revision 1.3-SNAPSHOT.
  5. commits everything.

After this has been done, you can continue working on the main trunk of your project in the new snapshot release. If you need to make changes to a previous revision, check out the old tag and create a branch from it. Eventually you’ll be able to release from the branch with a revision like 1.2.1.

Possible problems

Uncommitted changes

Problem: there are uncommitted changes in your local copy of the code.

Solution: commit or override your changes.

Unresolved dependencies

Problem: your project depends on a SNAPSHOT versions of another project. This is problematic because with a released version of the dependency, you will not be able to return to the exact project state that you currently have.

Solution: each dependency must be resolved. This will sometimes lead you on a chain of dependency resolution. The plugin seems to have the capability of resolving all the dependencies at once, but I have so far been a little leery of trusted the automated dependency resolution and have instead checked out and modified the dependency projects by hand. Also be aware that someone may have already versioned the dependency project and it might just be a matter of changing the version that you depend on.

Of course, you should co-ordinate other dependency releases with other people that are impacted by the release.

Your goal is to have no -SNAPSHOT dependencies in your pom.xml.

Weird problems from outer space

Problem: even though your application can be built properly, it cannot be released due to test failures.

Solution: the site:site target (which is run as part of the release process) may be the cause of your problem. It appears that site:site creates a different classpath than the standard test target. If this appears to be the case (that is, site:site does not run on its own), then it’s just the standard maven problem of tracking down multiple versions of a dependency.

“Too many open files” error

Problem: while running site:site, the release plugin reports a “too many open files” error.

Solution: this occurred quite frequently with the 1.0-beta-1 release of the wagon-webdav. Upgrade this to 1.0-beta-2.

Authorization errors

Problem: SVN reports authorization errors to the repository

Solution: run an “svn info” on the URL that was reported to be in error. If you’re asked for credentials, fill them in and this should cache them for the release:prepare. If you’re not asked for credentials, your problem is probably something else.

Cobertura complains

Problem: Error: data file /home/administrator/workspace/my-project/target/checkout/my-subproject/cobertura.ser does not exist

Solution: my-subproject has an empty src/main/java and/or src/test/java directories. Get rid of them.

The deploy takes an unreasonable amount of time

Problem: during the release:perform stage, the site:site target is called. It takes an especially long time, notably at this stage:

[INFO] Generating "Dependencies" report.

Solution: set the dependencyLocationsEnabled property to false.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-project-info-reports-plugin</artifactId>
    <configuration>
      <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
    </configuration>
</plugin>

or run maven with

-Ddependency.locations.enabled=false

Handy tricks

  • if you have several subprojects, you can release them all at once by releasing the parent project.
  • if a release fails and must be rolled back, be aware that the tag for the release will still be in svn. There are two possible solutions to this:
    • remove the tag from svn
    • pick a different version number for the release

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply