本篇文章给大家分享的是有关出现Maven JAR包冲突如何解决,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
Pom.xml / \ B C / \ / \ X Y X M
在以上依赖关系中项目除了会引入B、C还会引入X、Y、M的依赖包,但是如果B依赖的X版本会1.0而C依赖的X版本为2.0时,那最后项目使用的到底是X的1.0版本还是2.0版本就无法确定了。这是就要看ClassLoader的加载顺序,假设ClassLoader先加载1.0版本那就不会加载2.0版本,反之同理
使用mvn -Dverbose dependency:tree排查冲突
[INFO] +- org.apache.tomcat:tomcat-servlet-api:jar:7.0.70:compile [INFO] +- org.apache.tomcat:tomcat-jsp-api:jar:7.0.70:compile [INFO] | +- org.apache.tomcat:tomcat-el-api:jar:7.0.70:compile [INFO] | \- (org.apache.tomcat:tomcat-servlet-api:jar:7.0.70:compile - omitted for duplicate) [INFO] +- net.sf.jasperreports:jasperreports:jar:5.6.0:compile [INFO] | +- (commons-beanutils:commons-beanutils:jar:1.8.0:compile - omitted for conflict with 1.8.3) [INFO] | +- commons-collections:commons-collections:jar:3.2.1:compile [INFO] | +- commons-digester:commons-digester:jar:2.1:compile [INFO] | | +- (commons-beanutils:commons-beanutils:jar:1.8.3:compile - omitted for duplicate) [INFO] | | \- (commons-logging:commons-logging:jar:1.1.1:compile - omitted for duplicate)
递归依赖的关系列的算是比较清楚了,每行都是一个jar包,根据缩进可以看到依赖的关系
最后写着compile的就是编译成功的
最后写着omitted for duplicate的就是有JAR包被重复依赖了,但是JAR包的版本是一样的
最后写着omitted for conflict with xx的,说明和别的JAR包版本冲突了,该行的JAR包不会被引入
该命令可配合-Dincludes和-Dexcludes进行使用,只输出自己感兴趣/不感兴趣的JAR
参数格式为:[groupId]:[artifactId]:[type]:[version]
每个部分(冒号分割的部分)是支持*通配符的,如果要指定多个格式则可以用,分割,如:
mvn dependency:tree -Dincludes=javax.servlet,org.apache.*
解决冲突,使用exclusion标签将冲突的JAR排除
<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.8.3.2</version> <exclusions> <exclusion> <artifactId>guava</artifactId> <groupId>com.google.guava</groupId> </exclusion> <exclusion> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency>
解决了冲突后的树(解决冲突的策略是:就近原则,即离根近的依赖被采纳)
查看运行期类来源的JAR包
有时你以为解决了但是偏偏还是报类包冲突,典型症状是java.lang.ClassNotFoundException或Method不兼容等异常,这时你可以设置一个断点,在断点处通过下面这个工具类来查看Class所来源的JAR包
public class ClassLocationUtils { public static String where(final Class clazz) { if (clazz == null) { throw new IllegalArgumentException("null input: cls"); } URL result = null; final String clazzAsResource = clazz.getName().replace('.', '/').concat(".class"); final ProtectionDomain protectionDomain = clazz.getProtectionDomain(); if (protectionDomain != null) { final CodeSource codeSource = protectionDomain.getCodeSource(); if (codeSource != null) result = codeSource.getLocation(); if (result != null) { if ("file".equals(result.getProtocol())) { try { if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) { result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clazzAsResource)); } else if (new File(result.getFile()).isDirectory()) { result = new URL(result, clazzAsResource); } } catch (MalformedURLException ignore) { } } } } if (result == null) { final ClassLoader clsLoader = clazz.getClassLoader(); result = clsLoader != null ? clsLoader.getResource(clazzAsResource) : ClassLoader.getSystemResource(clazzAsResource); } return result.toString(); } }
然后随便写一个测试设置好断点,在执行到断点出使用ALT+F8动态执行代码,如
ClassLocationUtils.where(Logger.class)
以上就是出现Maven JAR包冲突如何解决,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。