jar包冲突排查

432 阅读2分钟

jar包冲突排查问题记录

mvn dependency:tree -Dverbose
注意不要省略`-Dverbose`,要不然不会显示被忽略的包。

2. 如何统一Jar包依赖

像上面截图所示,如果一个项目有N多个子项目构成,项目之间可能还有依赖关系,Jar包冲突不可避免,此时可采用父pom,统一对版本进行管理,一劳永逸。

通常做法,是在parent模块的pom文件中尽可能地声明所有相关依赖Jar包的版本,并在子pom中简单引用(不再指定版本)该构件即可。

比如在父pom.xml中定义Lombok的版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
</dependencyManagement>
复制代码

在子module中便可定义如下:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

3. 解决Jar包冲突的方法

这里基于Maven项目介绍几种场景下解决Jar冲突的方法:

  • Maven默认处理:采用此种方法,要牢记Maven依赖调节机制的基本原则,路径最近者优先和第一声明优先;

  • 排除法:上面Maven Helper的实例中已经讲到,可以将冲突的Jar包在pom.xml中通过exclude来进行排除;

  • 版本锁定法:如果项目中依赖同一Jar包的很多版本,一个个排除非常麻烦,此时可用版本锁定法,即直接明确引入指定版本的依赖。根据前面介绍Maven处理Jar包基本原则,此种方式的优先级最高。这种方法一般采用上面我们讲到的如何统一Jar包依赖的方式。

  • 我有时候不确定使用的是哪个正确的版本,这个时候我会在另外一个工程中试用一下,得到正常运行的jar的版本,然后再去有问题的工程去分析依赖数,把不正确的版本排除掉

4. Jar包冲突的本质

  • 情况一:项目依赖了同一Jar包的多个版本,并且选错了版本;
  • 情况二:同样的类在不同的Jar包中出现,导致JVM加载了错误的类;

5. Maven Jar包管理机制

  • 最短路径优先原则

依赖链路一:A -> X -> Y -> Z(21.0) 依赖链路二:B -> Q -> Z(20.0)

  • 最先声明优先原则

如果两个依赖的路径一样,最短路径优先原则是无法进行判断的,此时需要使用最先声明优先原则,也就是说,谁的声明在前则优先选择。 依赖链路一:A -> X -> Z(21.0) 依赖链路二:B -> Q -> Z(20.0)