Skip to main content

Managing version numbers in Maven with the Maven Versions plugin

Posted by johnsmart on August 18, 2010 at 4:43 AM PDT

If you have a Maven project of any size, particularly involving many modules or large numbers of dependencies, you have probably come across issues when updating your version numbers. Of course the Maven Release Plugin does a great job for updating version numbers as part of the automated release process, but there are times when it doesn't quite fit the bill, and version numbers are not limited to the main project versions.

The Versions Plugin very useful but not-so-well-known Maven plugin that gives you a number of tools in this direction. You should check out the website for a full list of everything this plugin can do, but here, I just want to cover a few highlights.

The Versions plugin, as the name suggests, helps you manage versions in your Maven projects. Versions of your artifacts, of course, but also versions of your dependencies and of your plugins. Let's take it for a spin.

The first thing you might want to do is to get an idea of the lay of the land, and see what dependencies in your project need updating. In large projects, the dependencies you use often become out-of-date over time, so it's nice to know when new ones are available. You can do this using the versions:display-dependency-updates command, which will list the dependencies you are currently using, and which ones are due for an update:


$ mvn versions:display-dependency-updates
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'versions'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Game of Life business logic module
[INFO]    task-segment: [versions:display-dependency-updates]
[INFO] ------------------------------------------------------------------------
[INFO] [versions:display-dependency-updates {execution: default-cli}]
[INFO] The following dependencies in Dependencies are using the newest version:
[INFO]   commons-cli:commons-cli .......................................... 1.2
[INFO]   org.hamcrest:hamcrest-all ........................................ 1.1
[INFO]
[INFO] The following dependencies in Dependencies have newer versions:
[INFO]   junit:junit ............................................... 4.4 -> 4.7
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL

 

 

 

 

Of course, plugins are in the same boat, so you might also want to run mvn versions:display-plugin-updates to check which plugins have more recent versions available. While it's at it, it will also let you know if any plugins don't have their versions specified (which is generally not a good idea):


$ mvn versions:display-plugin-updates
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'versions'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Game of Life business logic module
[INFO]    task-segment: [versions:display-plugin-updates]
[INFO] ------------------------------------------------------------------------
[INFO] [versions:display-plugin-updates {execution: default-cli}]
[INFO]
[INFO] The following plugin updates are available:
[INFO]   maven-checkstyle-plugin .................................. 2.2 -> 2.4
[INFO]   maven-clean-plugin ....................................... 2.2 -> 2.4
[INFO]   maven-deploy-plugin ...................................... 2.4 -> 2.5
[INFO]   maven-surefire-report-plugin ........................... 2.4.3 -> 2.5
[INFO]   org.codehaus.mojo:findbugs-maven-plugin ................ 1.2 -> 2.3.1
[INFO]
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin .......................... (from super-pom) 2.4
[WARNING]   maven-deploy-plugin ......................... (from super-pom) 2.5
[WARNING]   maven-site-plugin ........................... (from super-pom) 2.1
[WARNING]   maven-surefire-plugin ....................... (from super-pom) 2.5

 

 

 

 

But the Versions plugin doesn't just stop at reporting: you can also use it to actually update the version numbers in your pom.xml files. You do this via the mvn versions:set command. A bit like the Maven Release Plugin, but without the ceremony. In the following listing, we are upgrading our project version from 1.0.0-SNAPSHOT to 1.0.2-SNAPSHOT. This will update all of the versions in any modules as well, and also in any inter-module dependencies:


$ mvn versions:set -DnewVersion=1.0.2-SNAPSHOT
[INFO] ----------------------------------------------------------------------------------
[INFO] Building tweeter 1.0.0-SNAPSHOT
[INFO] ----------------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:1.2:set (default-cli) @ tweeter ---
[INFO] Searching for local aggregator root...
[INFO] Local aggregation root: /Users/johnsmart/Projects/Training/coding-dojos/wellington-coding-dojo/tweeter
[INFO] Processing co.nz.codingdojo.tweeter:tweeter
[INFO]     Updating project co.nz.codingdojo.tweeter:tweeter
[INFO]         from version 1.0.0-SNAPSHOT to 1.0.2-SNAPSHOT
[INFO]
[INFO] Processing co.nz.codingdojo.tweeter:tweeter-core
[INFO]     Updating parent co.nz.codingdojo.tweeter:tweeter
[INFO]         from version 1.0.0-SNAPSHOT to 1.0.2-SNAPSHOT
[INFO]
[INFO] Processing co.nz.codingdojo.tweeter:tweeter-services
[INFO]     Updating parent co.nz.codingdojo.tweeter:tweeter
[INFO]         from version 1.0.0-SNAPSHOT to 1.0.2-SNAPSHOT

 

 

 

 

But you might also want to update your dependency versions while your at it. If you want to update them all in one fell swoop, you can use the mvn versions:use-latest-versions command, as shown here:


$ mvn versions:use-latest-versions
[INFO] ----------------------------------------------------------------------------------
[INFO] Building tweeter 1.0.0-SNAPSHOT
[INFO] ----------------------------------------------------------------------------------
...
[INFO] artifact javax.servlet:jstl: checking for updates from Nexus
[INFO] artifact net.sourceforge.jwebunit:jwebunit-htmlunit-plugin: checking for updates from Nexus
[INFO] Updated net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:jar:null:2.1 to version 2.4
[INFO] artifact javax.servlet:servlet-api: checking for updates from Nexus
[INFO] Updated javax.servlet:servlet-api:jar:null:2.4 to version 2.5
[INFO] artifact org.springframework:spring-mock: checking for updates from Nexus
[INFO] artifact org.springframework:spring-core: checking for updates from Nexus
[INFO] Updated org.springframework:spring-core:jar:null:2.5.6 to version 3.0.3.RELEASE
[INFO] artifact com.google.inject.extensions:guice-servlet: checking for updates from Nexus
[INFO] ------------------------------------------------------------------------------------------------

 

 

 

 

Other goals worth mentioning are mvn versions:use-latest-releases, which replaces SNAPSHOT dependencies with the latest release, if they are more recent, and mvn versions:use-releases, which replaces any SNAPSHOT dependencies that have been released with the corresponding release versions. So, if you run mvn versions:use-releases, if would update from version 1.0.0-SNAPSHOT to version 1.0.0, if it is available, whereas mvn versions:use-latest-releases would bump it up to 1.0.2 if there is a 1.0.2 available. There is also versions:use-next-snapshots and versions:use-latest-snapshots, which do the same thing for SNAPSHOT versions.

Finally, once your happy with your new versions, use mvn versions:commit to set your changes in stone. This removes the backup files that the Versions plugin has been keeping, just in case. And if you finally decide it was all a horrible mistake, just run mvn versions:revert, and you will be back to the state you started with. Easy as!

If you want to learn more about the finer points of build automation with Maven, and a heap of other interesting stuff, be sure to check out the Java Power Tools bootcamps, coming up real soon in London and Canberra. Check it out!

Related Topics >>

Comments

I have a question concerning the goal versions:use-releases ...

I have a question concerning the goal versions:use-releases that should SNAPSHOT dependencies replace with RELEASE dependencies:

as I understand it, the plugin searches in any special maven repositories for a dependency with the same name just without the "-SNAPSHOT" stream. Where can I find out - or even better CONFIGURE - what repositories will be searched for the equivalent release versions?!

I've got a question :  I've just discovered ...

I've got a question : I've just discovered this plugin, and it helps me work out some details that I've been trying to resolve for some Hudson jobs. Using it as a step before release:prepare/perform and one step after gets the POM file into the state I want. The problem I have is how to get this to "check back in" to SVN.... I've got the right file out there in the Hudson workspace, but can't get it from there to where it could get picked up for developers after the release has gone out.

versions:commit locks it down, but doesn't put it back in SVN. Is there any simple way to do that as well??

Thanks a lot. It's a good

Thanks a lot. It's a good plugin indeed, I thought about "check updates" - like plugin once, it's good someone implemented it already.
Spring isn't following Maven conventions either so I get the following upgrade "suggestions":

[INFO] org.springframework:spring-core ............... 3.0.4.RELEASE -> 2.5.6
[INFO] org.springframework.batch:spring-batch-core ... 2.1.2.RELEASE -> 1.0.0-m3

Is version 2.2 newer than 2.2.1.1?

I think, there is a bug because version 2.2 is not newer than 2.2.1.1, and mvn versions:display-dependency-updates give that output:

[INFO] The following dependencies in Dependencies have newer versions:
[INFO] com.sun.xml.bind:jaxb-impl ............................ 2.2.1.1 -> 2.2

Non-standard version number?

The 4-digit version number (2.2.1.1) isn't using the Maven convention, so Maven won't be able to do the version comparisons properly. I'm not getting exactly that behaviour here using Maven 3 (it just doesn't attempt to do any calculations for jaxb-impl), but the end result is the same - looks like it doesn't like non-standard version numbers.