Maven versions, and why they sometimes aren't a good fit

· by [Joakim Verona] · Read in about 3 min · (495 words) ·

Many developers complain about Maven, how it is slow, and how it complicates life instead of making it easier. These developers might not remember how life was in the ancient days before Maven.

That said, Maven still has practical shortcomings, and one is the snapshot versioning scheme, when used in Continous Delivery pipelines.

From a developer point of view, there is no problem. Snapshots are nice. Just commit and the continuous Integration server builds a new swapshot. The CI server might even deploy the snapshot to a test server for us. Great!

From a Configuration Management point of view this is less than great. The tested artifact should be the same as the one deployed to production. If you change version strings in the pom files when you deploy to production, it is no longer the same artefact. People who claim that this is perfectly safe, has never heard about Murphys law.

Deploying snapshots to prod on the other hand, is not good for reasons of traceability. And if snapshots are good for production use, why do we even bother with versioning in the first place? Maven proponents might argue that the release plugin gives nice tool support for the version fidgeting, and therefore there is no problem.

So, what to do? Some people attempt to bind the Maven version to the version as defined by the source code management system. This might sort of work for scms with monotonically increasing version numbers, such as svn or bzr. You still get problems, such as the version changing for every commit, and thats maybe not workable at all times. for systems with sha1 commit ids such as git, you get other problems.

Other people attempt to use some kind of ‘latest’ feature to just build snapshots all the time, but then you completely bypass the Maven version mechanism, and you don’t get repeatable builds, which isn’t very good at all.

You can also use some form of build-numbers managed by your build server. That might be tempting, But making the buildserver do too much tends to create a single point of failure, and makes it hard to recreate the buildprocess on the developers build environment, and that’s not good for the DevOps concept.

Yet another solution is to just throw up your hands in the air in disgust, and just include the source tree of every dependency in your own source tree, and build everything on every release.

Here is another method which currently seems pretty good, but not withouth its own set of flaws.

  • Don’t actually use snapshots at all. Always use fixed numbering

. Arrange for the CI server to automatically increase versions in its copy of the source tree on every build

  • Have the CI server archive its version in the source code management system, so you get repeatable builds.

Hur du än vänder dig har du ändan bak, or in rough translation from swedish, However you turn, your behind is behind you.