What is dependency conflict

A dependency conflict is when a project depends on a JAR package that has multiple versions, resulting in a class package version conflict

Causes of dependency conflicts

Dependency conflicts are often caused by indirect dependencies between class packages. Each explicitly declared class package depends on some other implicit class package, which is indirectly introduced by Maven, causing package conflicts

How do you resolve dependency conflicts

First, look at the class JARS that cause dependency conflicts. Second, find the ones we don’t want and manually exclude them. The detailed procedure is as follows

1. View dependency conflicts

A, check for version conflicts via dependency:tree

mvn -Dverbose dependency:tree
Copy the code

When you type the above command, the following appears on the console

[INFO] org.example:hello:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-context:jar:5.2.7.RELEASE:compile
[INFO] |  +- (org.springframework:spring-aop:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO] |  +- org.springframework:spring-beans:jar:5.2.7.RELEASE:compile
[INFO] |  |  \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for duplicate)
[INFO] |  +- org.springframework:spring-core:jar:5.2.7.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-jcl:jar:5.2.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:5.2.7.RELEASE:compile
[INFO] |     \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for duplicate)
[INFO] \- org.springframework:spring-aop:jar:5.2.0.RELEASE:compile
[INFO]    +- (org.springframework:spring-beans:jar:5.2.0.RELEASE:compile - omitted for conflict with 5.2.7.RELEASE)
[INFO]    \- (org.springframework:spring-core:jar:5.2.0.RELEASE:compile - omitted for conflict with 5.2.7.RELEASE)
Copy the code

Where omitted for duplicate indicates that there is a jar package that is repeatedly dependent, and finally omitted for conflict with XXX indicates that there is a conflict with other JAR package versions, and the JAR package in this line will not be introduced. For example, there is a line that ends with omitted for conflict with 5.2.7.RELEASE, which means that the spring-core 5.2.0 version will not be referenced by the project, while the Spring-core 5.2.7 version will be

B. In the case of IDEA, install maven Helper plug-in to check for dependency conflicts

Maven Helper plug-in installed successfully, click on POM.xml and you will find a Dependency Analyzer view, as shown below

  • Conflicts (see Conflicts)
  • View All Dependencies as List
  • View All Dependencies as Tree

The figure above shows that there are three jars in conflict. Click the jar in conflict to view which jar is in conflict with, as shown in the figure below

2. Resolve conflicts

The pom.xml of the project looks like this

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> < version > 5.2.7. RELEASE < / version > < / dependency > < the dependency > < groupId > org. Springframework < / groupId > The < artifactId > spring - aop < / artifactId > < version > 5.2.0. RELEASE < / version > < / dependency > < / dependencies >Copy the code

By looking at the dependency tree, we know that the project will reference the 5.2.7.RELEASE Spring Core JAR, but not the 5.2.0 JAR. What should we do if we want to use spring Core 5.2.0?

A, the use of the first declaration of priority principle

The passed dependency of the jar defined first is used, i.e. the jar coordinates declared first from the top down in the pom.xml file refer to that JAR’s passed dependency first. So if we want to use the 5.2.0 version of the Spring Core package, we can change it to the following declaration

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> < version > 5.2.0. RELEASE < / version > < / dependency > < the dependency > < groupId > org. Springframework < / groupId > The < artifactId > spring - the context < / artifactId > < version > 5.2.7. RELEASE < / version > < / dependency > < / dependencies >Copy the code

Viewing the dependency tree

[INFO] org.example:hello:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-aop:jar:5.2.0.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:5.2.0.RELEASE:compile
[INFO] |  |  \- (org.springframework:spring-core:jar:5.2.0.RELEASE:compile - omitted for duplicate)
[INFO] |  \- org.springframework:spring-core:jar:5.2.0.RELEASE:compile
[INFO] |     \- org.springframework:spring-jcl:jar:5.2.0.RELEASE:compile
[INFO] \- org.springframework:spring-context:jar:5.2.7.RELEASE:compile
[INFO]    +- (org.springframework:spring-aop:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    +- (org.springframework:spring-beans:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    +- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)
[INFO]    \- org.springframework:spring-expression:jar:5.2.7.RELEASE:compile
[INFO]       \- (org.springframework:spring-core:jar:5.2.7.RELEASE:compile - omitted for conflict with 5.2.0.RELEASE)

Copy the code

Through the dependency tree, we can see that the project has introduced the 5.2.0 version of the Spring Core package

B, the use of the path closer to the priority principle

That is, the direct dependency level is higher than the passing dependency level. So we can add the following to the initial POM.xml

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> < version > 5.2.7. RELEASE < / version > < / dependency > < the dependency > < groupId > org. Springframework < / groupId > < artifactId > spring aop - < / artifactId > < version > 5.2.0. RELEASE < / version > < / dependency > < the dependency > < the groupId > org. Springframework < / groupId > < artifactId > spring - the core < / artifactId > < version > 5.2.0. RELEASE < / version > </dependency> </dependencies>Copy the code

C. Eliminate dependencies

If it is an IDEA, you can use the Maven Helper plug-in to exclude dependencies. Click on POm.xml, switch to Dependency Analyzer view, select All Dependencies as Tree, click on the JAR you want to exclude, and right click will bring up the Execlude option, as shown below

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> < version > 5.2.7. RELEASE < / version > < exclusions > < exclusion > < artifactId > spring - the core < / artifactId > <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> <dependency> < the groupId > org. Springframework < / groupId > < artifactId > spring aop - < / artifactId > < version > 5.2.0. RELEASE < / version > </dependency> </dependencies>Copy the code

4. Version lock

Version locking using dependencyManagement, which manages the version number of a project in a unified manner to ensure that the dependencies and versions of each project in the application are consistent.

If we only wanted to use spring Core 5.2.0 packages in our project, pom.xml could be changed as follows

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> The < artifactId > spring - the core < / artifactId > < version > 5.2.0. RELEASE < / version > < / dependency > < / dependencies > </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> < artifactId > spring - the context < / artifactId > < version > 5.2.7. RELEASE < / version > < / dependency > < the dependency > < the groupId > org. Springframework < / groupId > < artifactId > spring aop - < / artifactId > < version > 5.2.0. RELEASE < / version > </dependency> </dependencies>Copy the code

conclusion

DependencyManagement is a dependencyManagement method. It is recommended to use the Maven Helper plug-in to resolve dependency conflicts. It is recommended to use version locking to resolve dependency conflicts. So the subproject needs to display the dependencies that the declaration needs to use