Easily upgrade Java dependencies

To start with a cliche: the Java ecosystem continues to develop at a high pace. Various open source frameworks releasing versions, sometimes even multiple versions at the same time. This may quickly turn into a risk But how to deal with it?

Basically, you have two options. We’ll take a typical Maven-project as an example, which uses Commons Lang 3. See the end of this post if you prefer Gradle over Maven.

Automatic upgrades

Maybe the simplest way is automatic upgrading. You can achieve this by not specifying an exact version of your dependency, but instead specify a version range. If you would normally have this snippet in your POM:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.4</version>
</dependency>

You would replace that with:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>[3.4,4.0)</version>
</dependency>

Which basically says: give me a version of commons-lang3 which is at least 3.4, but not 4.0 or higher.

Manual upgrades & reporting

The above option is not without risks. Assuming our dependencies all follow semantic versioning principles, we would expect a minor version bump not to break anything that is not guaranteed. It also violates the reproducible build principle – a build of the same set of source files should always yield the same artifact(s). To prevent us from lagging behind, we could ask Maven to report on outdated versions by invoking the Versions Maven Plugin. This can be done either manually or automatically by invoking mvn versions:display-dependency-updates. This will give a quick overview of libraries that can be upgraded:

[INFO] artifact org.apache.commons:commons-lang3: checking for updates from central
[INFO] The following dependencies in Dependencies have newer versions:
[INFO]   org.apache.commons:commons-lang3 .......................... 3.4 -> 3.5

By the way, you can get a similar report on Maven plugins that your project uses by invoking mvn versions:display-plugin-updates. As an additional bonus, this will also tell you which plugin versions are specified by the Maven-version that you are using.

Gradle

If you prefer Gradle over Maven, you can use the com.github.ben-manes.versions by adding the following to you Gradle-file:

plugins {
  id "com.github.ben-manes.versions" version "0.13.0"
}

Invoking it without arguments by issuing gradle dependencyUpdates and you’ll get the text report:

------------------------------------------------------------
: Project Dependency Updates (report to plain text file)
------------------------------------------------------------
The following dependencies are using the latest milestone version:
 - com.github.ben-manes:gradle-versions-plugin:0.12.0
The following dependencies have later milestone versions:
 - org.apache.commons:commons-lang3 [3.4 -> 3.5]
Generated report file build/dependencyUpdates/report.txt