java 依赖包冲突,使用maven-shade-plugin解决
错误场景详情
1 | java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor; |
错误原因
出现这样的错误详情一般是由于有下面这样的包依赖情况
1 | A - B - C(guava version 18) |
A:代表我们所开发的当前项目
B和D:代表当前项目所依赖的项目
C:代表当前项目依赖的项目所依赖的项目
由于我们当前所开发的项目A依赖了B和D,B和D又依赖了项目C
我们打包运行项目时,maven只会将一个版本C(guava)打进包内(maven打包遇到相同依赖,最短路径优先,在路径相同时先在pom中声明优先)
比如此时打进包的版本是C(guava version 23.6-jre),那么很有可能在运行B中的一个方法时,调用C的一个方法,这个方法是C(guava version 18)中的一个方法,在C(guava version 23.6-jre)中并不存在,这时候就会报出java.lang.NoSuchMethodError
解决方案
使用maven-shade-plugin将所有B项目依赖的包全部打进B.jar中,并且给guava包的路径重命名为我们的自定义路径\
maven-shade-plugin基本功能
maven-shade-plugin提供了两大基本功能:
1、将依赖的jar包打包到当前jar包(常规打包是不会将所依赖jar包打进来的)
2、对依赖的jar包进行重命名(用于类的隔离,解决包冲突就是使用了这个功能)
解决示例
如下例,就可以在B项目中使用C(guava version 18),只不过import路径变成了我们自定的路径
1 |
|
使用maven-shade-plugin之前
1 | import Entity.Request; |
使用maven-shade-plugin之后编译后反编译结果
1 | import Entity.Request; |
最后将打好的包上传至我们的maven仓库,然后再在当前项目A中依赖,就没有依赖冲突了
1 | A - B - C(guava version 18, shade.com.google.common.collect.ImmutableMap) |
这样就可以做到将两个不同版本的包都引入使用,由于引入包路径不同,因此也没有冲突