Maven依赖jar包冲突常见的解决方法

项目中,经常会遇到ClassNotFound,NoSuchMethod异常,第一反应往往是类路径不对,jar没有正确的引用。第一步判断jar是否加载,还是 加载的jar由于maven依赖管理存在传递依赖,造成依赖的jar版本号不对,相应的类找不到,或者是相应类版本不对,没有对应的方法。

一 造成jar 冲突的原因:如果项目中存在对同一jar不同版本依赖的时候,maven 2根据最近原则,默认引用最靠近项目版本的jar,maven 2.0.9会根据最先声明原则 来引用相应版本的jar;无论那种方式,都会出现jar包冲突。在这里提一下gradle依赖,会依赖最新版本的jar。

二 判断jar是否正确的被引用 有两种方法:

1在项目启动时加上VM参数:-verbose:class

项目启动的时候会把所有加载的jar都打印出来 类似如下的信息:

classpath加载的jar

  1. -classpath /home/yao/tool/jdk1 .8 .0_25/jre/lib/jce.jar:
  2. /home/yao/tool/jdk1 .8 .0_25/jre/lib/resources.jar:
  3. /home/yao/tool/jdk1 .8 .0_25/jre/lib/rt.jar:
  4. /home/yao/tool/jdk1 .8 .0_25/jre/lib/management-agent.jar:
  5. /home/yao/tool/jdk1 .8 .0_25/jre/lib/jfxswt.jar:
  6. /home/yao/tool/jdk1 .8 .0_25/jre/lib/plugin.jar:
  7. /home/yao/tool/jdk1 .8 .0_25/jre/lib/javaws.jar:
  8. /home/yao/tool/jdk1 .8 .0_25/jre/lib/charsets.jar:
  9. /home/yao/tool/jdk1 .8 .0_25/jre/lib/jsse.jar:
  10. /home/yao/tool/jdk1 .8 .0_25/jre/lib/deploy.jar:
  11. /home/yao/tool/jdk1 .8 .0_25/jre/lib/jfr.jar:
  12. /home/yao/tool/jdk1 .8 .0_25/jre/lib/ext/localedata.jar:
  13. /home/yao/tool/jdk1 .8 .0_25/jre/lib/ext/nashorn.jar:
  14. /home/yao/tool/jdk1 .8 .0_25/jre/lib/ext/jfxrt.jar:
  15. /home/yao/tool/jdk1 .8 .0_25/jre/lib/ext/sunjce_provider.jar:
  16. ...............等等

具体load的类

[Loaded java.lang.Object from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.io.Serializable from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.String from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.reflect.AnnotatedElement from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.reflect.Type from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
[Loaded java.lang.Class from /home/yao/tool/jdk1.8.0_25/jre/lib/rt.jar]
..................等等

我们可以通过上面的信息查找对应的jar是否正确的被依赖,具体类加载情况,同时可以看到版本号,确定是否由于依赖冲突造成的jar引用不正确;

2 通过maven自带的工具:‍‍mvn dependency:tree

具体后面可以加 -Dverbose 参数 ,详细参数可以去自己搜,这里不详细介绍。

比如分析如下POM

运行: mvn dependency:tree -Dverbose

 <dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.2-FINAL</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.7.0</version>
        </dependency>
    </dependencies>

输出结果:

  1. [ INFO] ------------------------------------------------------------------------
  2. [ INFO]
  3. [ INFO] --- maven-dependency- plugin: 2.8 :tree (default-cli) @ Dependency ---
  4. [ INFO] com. yao: Dependency :pom : 1.0- SNAPSHOT
  5. [ INFO] +- org.apache. poi: poi: jar: 3.2- FINAL :compile
  6. [ INFO] | +- commons- logging: commons- logging: jar: 1.1 :compile
  7. [ INFO ] | | \- log4j: log4j: jar: 1.2 . 13 :compile
  8. [ INFO ] | \- ( log4j: log4j: jar: 1.2. 13 :compile - scope updated from runtime; omitted for duplicate)
  9. [ INFO] \- commons- beanutils:commons- beanutils: jar: 1.7. 0 :compile
  10. [ INFO] \- (commons- logging:commons- logging: jar: 1.0. 3 :compile - omitted for conflict with 1.1)
  11. [ INFO] ------------------------------------------------------------------------

通过里面的信息可以看到 两个jar都commons-logging存在依赖,但是版本不同。里面的详细信息显示引用了 commons-logging:commons-logging:jar:1.1 去掉了commons-logging:commons-logging:jar:1.0.3 (omitted for duplicate)。

通过以上方法我们可以看到项目中引用jar版本号;接下来就是如何排除掉我们不想要版本的jar;

三 通过Idea intellij 中的Show Dependencies的工具去除重复的jar

在Pom.xml文件上右击 选择 Diagrams -> Show Dependencies 即可查看Pom的依赖图,通过图可以很容易的看到依赖冲突的jar,exculude掉不想要的版本jar即可。

Maven依赖jar包冲突常见的解决方法

猜你喜欢

转载自blog.csdn.net/a_blackmoon/article/details/81064836