John is an experienced consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Sydney, Australia. Well known in the Java community for his many published articles, and as author of Java Power Tools and Jenkins: The Definitive Guide, and founder of the open source Thucydides Automated Acceptance Test Library project, John helps organisations to optimize their Java development processes and infrastructures and provides training and mentoring in agile development, automated testing practices, continuous integration and delivery, and open source technologies in general. John is the CEO of Wakaleo Consulting, and runs several Training Courses on open source Java development tools and best practices. John is a DZone MVB and is not an employee of DZone and has posted 117 posts at DZone. You can read more from them at their website. View Full User Profile

Managing Version Numbers in Maven With the Maven Versions Plugin

08.19.2010
| 9793 views |
  • submit to reddit

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!

From http://weblogs.java.net/blog/johnsmart/archive/2010/08/18/managing-version-numbers-maven-maven-version-plugin

Published at DZone with permission of John Ferguson Smart, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Patrick Cornelissen replied on Thu, 2010/08/19 - 12:47am

Thanks for bringing this plugin up, it's really useful and I somehow have forgotten it!

John J. Franey replied on Thu, 2010/08/19 - 11:51am

Thanks for helping me learn something new today. Not only about the versions plugin.... While was scanning the maven plugins page, looking for versions, my eyes stumbled over the 'shade' plugin. I don't know why its called 'shade' or how long it has been around. Its the first I noticed it. It too is a useful plugin. It is a short hand for the assembly plugin and is especially useful because it easily builds an artifact as product (as opposed to artifact as library). This and the versions plugin are two plugins I needed today. Thanks.

Burkhard Graves replied on Fri, 2010/08/20 - 5:00am

Nice tool in principle, but unfortunately sometimes wrong, e.g.:

[INFO] The following dependencies in Dependency Management have newer versions:
[INFO] c3p0:c3p0 ........................................... 0.9.1.2 -> 0.9.0
[INFO] org.springframework:spring-core ............... 3.0.4.RELEASE -> 2.5.

 

John Ferguson Smart replied on Fri, 2010/08/20 - 3:27pm

Actually, that's Maven - Maven only guarantees to be able to compare version numbers in the standard 3-number format (0.9.0 is, but 0.9.1.2 isn't; 3.0.4-RELEASE would have been, but 3.0.4.RELEASE isn't). That's why the plugin behaves strangely with version numbers like this.

King Sam replied on Fri, 2012/02/24 - 10:17am

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.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.