Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solving Maven dependency convergence issues

People also ask

What is Maven dependency convergence error?

This rule requires that dependency version numbers converge. If a project has two dependencies, A and B, both depending on the same artifact, C, this rule will fail the build if A depends on a different version of C than the version of C depended on by B.

How do you exclude a transitive dependency in Maven?

Exclude the transitive dependencyOpen the dependency POM and find the transitive dependency you want to exclude. Copy groupId and artifactId . In your project POM, underneath your active dependency, enter exclusions and using code completion paste the copied info of the dependency you want to exclude.

What is banned dependency in Maven?

This rule checks the dependencies and fails if any of the matching excludes are found. The following parameters are supported by this rule: searchTransitive - if transitive dependencies should be checked.

What is Maven enforcer plugin?

Maven Enforcer Plugin is a plugin that helps you enforce rules such as which dependencies to use in your project, avoiding duplicate dependencies, banned dependencies and enforcing restrictions on transitive dependencies.


We all agree that JUnit should never be set to another scope than test. Generally speaking I don't think either that there is another solution than excluding the unwanted dependency, so we all agree that your are right to do it.

A SIMPLE CASE :

As Andreas Krueger says, there may be a risk with versions (I actually encountered it). Let say that the project's dependencies are the following:

+-foo:bar:1.0-SNAPSHOT
  +-group1:projectA:2.0
     +-group2:projectB:3.8.1
  +-group2:projectB:4.11

Note that it is only a mere simplification of your case. Seeing this dependency tree, you would exclude the dependency projectB given by projectA :

<dependency>
  <groupId>group1</groupId>
  <artifactId>projectA</artifactId>
  <version>2.0</version>
  <exclusions>
    <exclusion>
      <groupId>group2</groupId>
      <artifactId>projectB</artifactId>
    </exclusion>
  </exclusions>
</dependency>

After packaging the project with maven, the remaining dependency would be group2-someProjectB-4.11.jar, version 4.11 and not 3.8.1. Everything would be fine and the project would run without encountering any problem at all.

Then, a while after, let say that you decide to upgrade to the next version of project A, version 3.0 which adds new great features :

<dependency>
  <groupId>group1</groupId>
  <artifactId>projectA</artifactId>
  <version>3.0</version>
  <exclusions>
    <exclusion>
      <groupId>group2</groupId>
      <artifactId>projectB</artifactId>
    </exclusion>
  </exclusions>
</dependency>

The problem is that you are not aware yet that projectA version 3.0 also have upgraded its dependency projectB to version 5.0 :

+-foo:bar:1.0-SNAPSHOT
  +-group1:projectA:3.0
     +-group2:projectB:5.0
  +-group2:projectB:4.11

In that case, the exclusion you would have made a while ago excludes projectB version 5.0.

However, projectA version 3.0 needs the improvements from project B version 5.0. Because of the exclusion, after packaging the project with maven, the remaining dependency would be group2-someProjectB-4.11.jar, version 4.11 and not 5.0. At the moment you use any of projectA's new features, the program wouldn't run correctly.

WHAT WAS THE SOLUTION ?

I encountered this problem in a Java-EE project.

A team developped database services. They packaged it as projectA. Each time they updated the services, they also updated a file listing all their current dependencies and the current versions.

ProjectA was a dependency for the Java-EE project I was working on. Each time the service-team updated ProjectA, I also checked the versions' updates.

In fact, there is no harm in excluding a dependency. But each time you update a dependency where an exclusion has been set, You have to check :

  • if this exclusion still makes sense.
  • if you need to upgrade the version of the excluded dependency in your own project.

I guess maven exclusions are like kitchen knifes. It's sharp, cuts vegetables with no effort, but requires care when handling it...


If JUnit as an artifact is coming through as a dependency in compile scope, it is a bug of one of your libraries, here: ca.juliusdavies.

JUnit should always be included in test scope. Thus, it is not packed into the produced .jar, .war or .ear file, on successful build.

Generally speaking, there is no harm in excluding already included dependencies, as when library 1 and library 2 share one common dependency.

The only problem, of course, that can occur, is when library 1 and library 2 include different versions of the same dependent artifact. This can cause run-time errors, when the features of the library have changed. Fortunately, this is not often the case, unless the difference in the version numbers is great. In general, it is advisable to include the latest dependency version and exlude the older one. This is most of the time viable.

If not, check wheter there are updates to the first-level dependencies of your project.