Above all that same artifact doesn`t use different versions of the same dependency.
+-ProjectA:B:0.1
+-commons-validator:commons-validator:1.6
+-commons-beanutils:commons-beanutils:1.9.2
+-commons-collections:commons-collections:3.2.1
and
+-ProjectA:B:0.1
+-commons-validator:commons-validator:1.6
+-commons-collections:commons-collections:3.2.2
Dependency commons-validator:commons-validator:1.6 uses commons-collections:commons-collections:3.2.2 directly and commons-collections:commons-collections:3.2.1 transitively (dependency of an other dependency). Maven`s dependency mediation will resolve this conflict based on neares-newest principle.
Take a look at these:
[1] Dependency Mechanism
[2] Dependency Mediation and Conflict Resolution
The maven-enforcer-plugin`s dependencyConvergence rule works fine.
As the documentation says:
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 then the version of C depended on by B.
Because commons-validator (A) and commons-beanutils (B) depending on commons-collections (C) and those dependecies has different versions this behaviour is totally reasonable.
You decide what do you want to exactly do.
Keep using dependencyConvergence rule and resolve this error
In this case just define commons-collections, commons-logging and commons-validator in <dependencyManagement> section and put those dependencies as managed dependences in your project.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
</dependencies>
I think it needs a lot of overwork and after a while your project model will be unmaintenable. On the other hand Dependency Mediation rule resolves this problem.
Use other rule e.g. requireUpperBoundDeps
This rule is designed to investigagte if a resolved dependency during a build is lower than all transitive dependeny declarations. E.g. it will fail if your project depending on commons-collections:3.0 but commons-validator requires newer version commons-collections:3.2.2
<dependencies>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
Forget enforcer and trust in Dependency Mediation
Almost all cases this is the right decision because Dependency Mediation is works fine.