此异常说明你的依赖里面出现了多个相同的包但是版本不一样,导致冲突
第一种解决办法:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
</exclusions>
</dependency>
像上面,如果确定这个冲突的依赖包没用了,就可以使用exclusion标签做剔除。如果想统一这个包的版本,那就剔除这个包后,再导入你希望导入的这个包的版本,如下:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
第二种方法
假设你有冲突的那个包版本比如2.8.1 ,因为冲突,使用了当前项目中该包更低的版本2.5.1,导致有些类找不到,出现例如java.lang.NoClassDefFoundError: org/apache/commons/collections/FastHashMap
的错误
此时,就说明低版本的包缺少这个类,而当前包依赖的是高版本的包来开发的(2.8.1),自然是报错。
除了第一种统一包版本的办法,在maven中,依赖的导入顺序也会影响遇到冲突的时候优先使用哪个版本的包,一般是从上往下依次扫描pom文件,遇到冲突则后者会使用前者的依赖版本。
此时可以调换两个冲突包在pom中的位置,这样就能够让高版本的包覆盖低版本的冲突包(一般高版本的包都会向下兼容低版本的包)
第三种方法
有时候你发现,平常时代码运行的好好的,但是某次重启之后,就报了某个类的某个方法找不到的异常,很是诡异。这个时候要冷静下来,推测是maven扫包时的顺序导致低版本的包恰好优先被读取了。我们要做到的是:
- 进入报异常的机器,下载arhtas,通过arthas连接到目标进程中。
- 通过arthas的sc命令,把报错的类检查下,是否真的没有这个类。如果有的话,需要你下载sc的内容,拷贝到本地作为对比内容。
- 在做完上一步操作之后,回到你本地的代码,你发现本地应用这个类并没有报错。这时候我推荐一个工具来分析本地代码包冲突的情况:打开IntellJ IDEA 的偏好设置(Preferences)中的Plugins,搜索Maven Helper进行安装。使用这个插件提供的Dependency Analyzer功能,对包依赖进行分析;
然后找到你冲突那个类所在的那个包名,通过analyzer查看,这个类所在的包在哪些依赖里面可能存在,是否存在冲突(conflict)。找到可疑的包后,对这个jar包进行分析,通过jd-gui工具反编译里面的class文件,找到和当前一样的问题类,对比两者,重点看看error提示的方法是否都存在于两个class文件中。一般情况到这一步你就清楚了。
当然,对于有些jar包它编译的时候把所有的依赖都打到了同一个jar里面,这样就不能再时候exclude排除依赖再使用同一个版本的方法解决冲突了,所以建议以后打包采用分开不同jar单独打,尽量不要集成到一个jar里。