Saturday, November 29, 2014

Maven: Transitive Dependency Version Conflict Resolution

To display the dependency tree of a project projects (which includes the dependencies of the project as well as the dependencies of the dependencies...), navigate to the project root folder (which contains the pom file) and run the following command:

> mvn dependency:tree

To save the dependency true to a file said dependency-tree.txt, run the following command:

> mvn dependency:tree > dependency-tree.txt

This command allows user to detect which transitive dependencies are referenced by the project. As a project many have quite a number of direct dependencies (at level 0 dependency, i.e.), which may in turn has dependency on some other library or components. It may happens that same transitive dependency but with different versions but be referenced by the project. In this case, a version conflict on the transitive dependency will arise. The next section explains which version of the transitive dependency maven will take when this happens.

Determine which version of the same dependency will be taken: Nearest First and First Found

If the project has two different dependencies A and B, and A and B both have another dependency C but with different versions of C. For example, if A depends on C:1.1.0 and B depends on C:1.1.2, then maven uses the follow rule to decide whether C:1.1.0 or C:1.1.2 is to be taken.

1. Nearest First: suppose A is at level 0 dependency to the project (i.e. the project directly depends on A) and B is at level 1 dependency to the same project (i.e. the project depends on another jar, said, D, which then depends on B). Then  C:1.1.0 is be loaded as A is "nearer" to the project.
2. First Found: if A and B is at the same dependency level, but A is first found by the project (e.g. suppose A and B are at level 0, and A is included in the pom file before B), then C:1.1.0 will be taken.

Control which version of the same dependency to be taken: exclusion and optional

Suppose following the above procedure, and the maven takes in C:1.1.0, in this case, the project may crash because its dependency B requires C:1.1.2 (e.g. common exception such as "ClassDefNotFoundException"). In such scenerio, we can ask A to exclude C:1.1.0, then maven will take in C:1.1.2 instead.

<dependency>
<groupId>groupId.A</groupId>
<artifactId>A</artifactId>
<version>${A.version}</version>
<exclusion>
<groupId>groupId.C</groupId>
<artifactId>C</artifactId>
</exclusion>

Another way to to specify C as optional as A's pom file (i.e. include a tag <optional>true</optional>.in dependency section of C).





No comments:

Post a Comment