Managing Maven Dependencies - tips and tricks

Written by Kees van Dieren

Managing Maven Dependencies - tips and tricks

Large Java projects often struggle to get their dependencies right. We share best practices and Maven plugins that help solving maintenance problems and help keep the build healthy.

Define versions in dependencyManagement only

Maven supports defining project dependency versions on different locations: in project / dependencyManagement / dependencies and project / dependencies.

Don’t: define versions in project / dependencies.

Do: define versions in project / dependencyManagement / dependencies.

For multi-module Maven projects, define versions in dependencyManagement of the project root pom.xml.

Every developer working with Maven projects should understand this. Read Maven Dependencies documentation to learn about the background of this recommendation.

Use BOM pom for multi-module dependencies

Various projects (such as Spring Framework) have BOM pom files. For dependencies with multiple modules, this ensures that those modules are all of the same version. Concepts are explained in the Maven guide, section Importing Dependencies. Another good introduction is provided by Baeldungs Spring with Maven BOM article.

Detect duplicate classes on the classpath

Some classes are available in multiple dependencies. Having different dependencies with the same classes in one product, can cause huge problems. The version of the class loaded is unpredictable. This can lead to (hard-to-debug) build and runtime errors.

Some causes of how classes get duplicated:

  • Dependencies get relocated, for example library javassist used to be in javassist:javassist, but was moved to org.javassists:javassist.
  • Dependencies get merged. For example, Google Collections, has been merged into Google Guava.
  • Dependencies pack external classes inside their own jar (instead of letting their dependencies be managed by Maven).
  • Some packages manage to put class-files multiple times in a JAR file, and still to be used by many projects (e.g. XMLBeans).

Do:

  • Detect duplicate classes using the Ban Duplicate Classes rule of Maven Enforcer plugin.
  • Fail the build when duplicates are found.
  • Configure an ignore list for duplicate classes you cannot get rid of.
  • Exclude libraries from the build that cause duplicates.

Require the latest version of dependencies for version conflicts

Sometimes one dependency is used multiple times by transitive dependencies. Often happens with common libraries like Guava, Apache Commons Lang, Apache Commons IO etc.

Maven does not choose the correct version automatically. Maven selects the version of the dependency with the shortest path in the dependency tree, which is not always the latest version. In general, what is needed, is the latest version.

Do:

  • Detect wrong versions resolved by Maven using Require Upper Bound Dependencies Enforcer plugin rule.
  • Set the version of the conflicted dependency in dependencyManagement in the project root pom.xml file.

Keep dependencies up-to-date

Keep your dependencies up-to-date using Versions Maven Plugin. This plugin reduces automates this task, and as libraries are following the semantic versioning principle better and better, this plugin can take this task with less effort of developers.

Always stay up-to-date with the latest minor version of libraries. This saves the product often from vulnerabilities and reduces the chance for incompatibilities when adding more third-party libraries to the project.

Check dependencies for vulnerabilities

Security vulnerabilities are found on daily basis in java libraries. Common Vulnerabilities and Exposures (CVE) of software components are collected by NIST.

There is an OWASP Maven dependency-check plugin, which can check for CVEs. It uses the NIST database as source, and scans Java code and Javascript code in the full dependency tree.

Do:

  • Configure the plugin.
  • Create a nightly build on the CI server that runs the plugin.

Detect dependency-problems with dependency:analyze

Maven provides a plugin that can find out if your project has unused dependencies, or is using dependencies without declaring the dependency itself.

The Maven dependency:analyze goal helps to find those dependencies. Removing unused dependencies is worth spending time on, as it keeps you project as small as possible which makes it easier to adapt to future needs.

Analyze dependency problems in a smart way

Regularly analyze dependencies and see if actual versions resolved are the ones expected.

To view the list of Maven dependencies in a project:

mvn depenency:tree | less

To view the pom.xml with versions of all dependencies actually used:

mvn help:effective-pom | less

For products packaging a WAR or Spring-Boot JAR, you can also check the exploded package, and see if any unexpected libraries are in there.

Conclusion

As you can see, there are many preventive measures available to keep your project healthy.

Work with us

Looking for help to improve your Maven builds? Let us support you! Mail us at info@squins.com.

We’re looking for new software craftsman to join our company. View our vacancy for Java Developer (in 🇳🇱)

Posted in:  Java  Maven  Architecture  Security 

Kees van Dieren, CEO

We've years of experience helping startups and scale-ups to work more efficient by creating apps that are fit their needs.

Let’s talk. We look forward to exploring the opportunity to help your company too.

Go ahead and send us a message. We look forward to exploring the opportunity to help you too.