记一次修复maven打包类加载冲突

编译kg-buslogic时遇到类加载冲突,提示

1
2
3
[ERROR] /Users/ziqian/project/yisou/kg-buslogic/src/main/java/cn/creditease/bdp/kg/buslogic/merged/ThridPartClien t.java:[94,16] 找不到符号
[ERROR] 符号: 方法 setConfig(org.apache.http.client.config.RequestConfig)
[ERROR] 位置: 类型为org.apache.http.client.methods.HttpRequestBase的变量 request

查了一下应该是org.apache.httpcomponents.httpclient冲突了,因为新加的kg-engin中调用了jena-arq,arq依赖httclient 4.2,而我们依赖4.5。4.2里是没有这个方法的。

按照正常处理方法,直接把kg-engine里面的httpclient exclude即可,但是这次操作以后不行。各种exclude都没有效果,于是决定去看一下mvn编译时HttpRequestBase在哪里加载。查看的方法为利用mvn插件:

1
2
3
4
5
6
7
8
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<verbose>true</verbose>
</configuration>
</plugin>

利用maven-compiler-plugin插件,并且设置verbose就可以查到。

这时一看,HttpReqBase居然是在kg-engin里加载的,非常奇怪。于是回去看了一下kg-engin的打包方式。因为之前是单独跑engine,并且他打包使用了maven-shade-plugin插件打包成一个shard。这里就是问题所在。shard是将所有的.class打成一个大包,之后mvn install是install了这个大包,所以他的class会有这个HttpRequestBase,编译时会先load它并且无法被exclude,所有会拦住后面的httpClient4.5。因此会被后面依赖的包打包时不能使用shard方法。

将kg-engin的shard打包部分删掉,重新mvn install kg-engine,之后buslogic就可以成功编译了。

这里引入了另一个问题,mvn编译时.class的加载和pom文件中dependency的顺序有什么关系?感觉是按照先后顺序来的,因为其实上面的问题在不改kg-engine的前提下,直接把httpclient 4.5的dependency放到kg-engine前面也可以解决这个问题。

网上有一个文章说maven依赖冲突时的加载顺序:

依赖冲突:

这个是dependency的GA一样但V不同,Maven自2.9(还是2.0.9,不清楚了)开始为了确保确定性,采用如下方法解决:

  1. 依赖路径浅的优先:
    • 假设,A->B->slf4j:1.6.2,A->C->E->slf4j:1.4.1,则slf4j:1.6.2优先
  2. 声明优先,如果在dependencyManagement中声明的话会优先采用对应插件
  3. 覆写优先,子POM内声明的优先于父POM中的依赖

本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证,欢迎转载,但转载请注明来自http://thousandhu.github.io,并保持转载后文章内容的完整。本人保留所有版权相关权利。

本文链接:http://thousandhu.github.io/2016/05/19/记一次修复maven打包类加载冲突/