前言

使用 maven 管理项目一开始方便,但是随着依赖越来越多就会越来越麻烦。最典型的一个问题即是发生JAR的依赖冲突,如下介绍几种常见的处理办法。

统一为高版本号

当依赖的两个JAR包版本发送冲突时,存在两种情况:

一种是当高版本兼容低版本JAR包,此时的策略是将低版本的依赖包升级为高版本。具体方法:

- 直接修改版本号为高版本号,通过修改vesion

- 当依赖的是开源JAR包(冲突JAR是通过传递依赖引入)此时无法显示修改version,可以通过exclusion方法进行排除,如下排除spring-boot-starter-web引入的2.9.8的jacskon

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </exclusion> </exclusions> <version>2.1.2.RELEASE</version> </dependency>统一为低版本号

进行降版本的操作前提,要确认对于引入高版本JAR的所有功能都不能产生影响。一般情况下,不建议这样操作。

如何找到冲突的JAR

上两节介绍了如何解决冲突,除了在运行系统中报错日志中识别到冲突的JAR,还可以利用IDE的maven help插件协助查看

点击POM文件,提供Dependency Analyzer的Tab视图查看所有依赖及关系,包括冲突项,非常方便

同时,也可以使用命令:

mvn dependency:tree
mvn dependency:tree > out.txt

导出项目的依赖树内容

使用maven-shade-plugin解决JAR冲突

JAR冲突的根本原因是类的冲突,即存在两个同全路径名的类,所以如能够修改类的全路径名,即冲突自然解决。为些插件maven-shade-plugin可以协助完成该操作。如下,在引入guava包的工程中

<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration><!-- <minimizeJar>true</minimizeJar>--><!-- <artifactSet>--><!-- <excludes>--><!-- <exclude>org.projectlombok:lombok</exclude>--><!-- </excludes>--><!-- </artifactSet>--> <relocations> <relocation> <!--表示将所有com.google.common引入包修改成my_guava.common--> <pattern>com.google.common</pattern> <shadedPattern>my_guava.common</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build>

使用上述插件,最终mvn package出来的JAR包,会一并包含guava的依赖,同时修改所有包名:

使用maven-shade-plugin会默认将所有依赖都打进JAR包(除依赖使用的scope为provider),可以使用artifactSet配置进行排除,见上文pom注释处,更多配置可参考:

http://www.iigrowing.cn/maven-shade-plugin_ru_men_zhi_nan.html

五、SOFABoot 类隔离

https://zhuanlan.zhihu.com/p/36909393