Maven第八章:如何解决Maven的jar版本冲突
前言
本文重点讲解Maven依赖冲突原因,maven依赖原则以及如何利用idea Maven Helper插件分析解决问题。
背景
开发过程中引入第三方jar遇到依赖冲突的,非常影响开发,甚至大部分时间都在调试版本兼容。
Caused by:java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException
Caused by: java.lang.NoClassDefFoundError
Maven依赖冲突原因
在项目中使用了多个版本的同一个jar包,就会产生jar冲突问题。Maven会尝试将所有的依赖项解析为同一版本,但如果有多个版本的同一个jar包存在,就会导致构建失败。
Maven依赖原则
- 依赖管理优先
优先按照dependencyMangement
元素中指定的版本声明 - 最短路径优先
按照依赖传递关系,使用最近依赖版本 - 声明顺序优先
路径相同则按照依赖在pom.xml中被声明的顺序决定,定义在pom.xml顺序靠前
的版本生效
Maven Helper插件如何分析与解决问题
1、打开IDEA 插件配置界面 File -> Settings ->Plugins,在搜索框中输入Maven Helper就可以搜索到,点击 install
- 重启idea
- 编辑pom.xml ,编辑框会出现一个Dependency Analyzer ,如下图所示
- 在pom.xml配置文件,引入 junit,spring-boot-starter-web,spring-boot-starter-docker
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.13</version>
</dependency>
<dependency>
<groupId>nl.42</groupId>
<artifactId>spring-boot-starter-docker</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>nl.42</groupId>
<artifactId>spring-boot-starter-docker</artifactId>
</dependency>
</dependencies>
- maven update ,下载更新引入依赖
- 进入Maven Help插件分析,有依赖版本冲突,冲突的jar : slf4j-api、snakeyaml、logback-classic
<artifactId>logback-classic</artifactId>
版本冲突:spring-boot-starter-web依赖引入 1.2.12版本;spring-boot-starter-docker 依赖引入 1.2.3版本。
<artifactId>slf4j-api</artifactId>
版本冲突:spring-boot-starter-web依赖引入 1.7.36、1.7.35 版本;spring-boot-starter-docker 依赖引入 1.7.25 版本。
<artifactId>snakeyaml</artifactId>
版本冲突:spring-boot-starter-web依赖引入 1.30 版本;spring-boot-starter-docker 依赖引入 1.18 版本。
- 以上把相关冲突分析梳理清晰之后,就是进行版本处理,推荐
版本限定
原则处理。利用mavendependencyManagement
进行版本统一管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.13</version>
</dependency>
<dependency>
<groupId>nl.42</groupId>
<artifactId>spring-boot-starter-docker</artifactId>
<version>1.0.3</version>
</dependency>
<!--统一版本约定-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.35</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.30</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
</dependencyManagement>
- maven 更新下载,再编辑pom.xml ,检测冲突,已经解决了