最后更新:2026-07-10
适用场景:Maven 依赖冲突、Jar 包版本冲突、NoSuchMethodError、ClassNotFoundException、NoClassDefFoundError、dependency:tree 使用、exclusions 排除依赖、dependencyManagement 统一版本

Java 项目里很多奇怪报错,表面看是代码问题,实际可能是 Maven 依赖冲突。

常见现象包括:

本地能跑,服务器不能跑
IDEA能跑,打包后不能跑
升级一个依赖后,另一个功能突然报错
NoSuchMethodError
ClassNotFoundException
NoClassDefFoundError
ClassCastException
BeanCreationException
Failed to instantiate

尤其是 Spring Boot、MyBatis、Jackson、Netty、Guava、SLF4J、Logback、Tomcat、Elasticsearch、Redisson、Dubbo、ShardingSphere 等依赖比较多的项目,很容易遇到版本冲突。

Maven 会自动引入传递依赖,也就是你引入 A,A 又依赖 B,B 又依赖 C,最终这些依赖都会进入你的项目 classpath;Maven 官方文档也说明,传递依赖会让依赖图快速变大,因此 Maven 提供了依赖调解、依赖管理、optional、exclusions 等机制来控制最终进入项目的依赖。(Apache Maven)

本文整理一套 Maven 依赖冲突排查流程,包括:

dependency:tree 怎么用
如何定位冲突依赖来源
如何排除传递依赖
如何用 dependencyManagement 统一版本
如何排查 NoSuchMethodError / ClassNotFoundException
Spring Boot 项目如何避免乱改版本
IDEA 中如何查看 Maven 依赖图

一、先说结论:Maven依赖冲突排查顺序

遇到 Maven 依赖冲突,建议按这个顺序处理:

1. 先看完整报错,确认是类找不到、方法找不到,还是版本不兼容
2. 用 mvn dependency:tree 查看完整依赖树
3. 用 -Dincludes 过滤目标依赖
4. 找到冲突 Jar 是被哪个依赖传递进来的
5. 判断应该升级、降级、排除,还是统一版本
6. 用 exclusions 排除不需要的传递依赖
7. 用 dependencyManagement 统一依赖版本
8. Spring Boot 项目优先使用官方 BOM,不要随便覆盖核心依赖版本
9. 执行 mvn clean test / mvn clean package 验证
10. 如果仍然异常,再检查打包结果、运行环境和服务器 classpath

不要一上来就做这些事:

直接删除整个 .m2 仓库
随便升级所有依赖到最新版
在 pom.xml 里到处写 exclusions
强行覆盖 Spring Boot 管理的版本
只看 IDEA 红不红,不看 dependency:tree

依赖冲突排查的核心是:

先确认最终生效的是哪个版本
再确认它是从哪里来的
最后决定怎么处理

二、什么是Maven依赖冲突?

简单说,Maven 依赖冲突就是:

项目中多个依赖同时需要同一个 Jar 的不同版本

例如:

A 依赖 guava 18.0
B 依赖 guava 32.1.3-jre

最终项目里只能有一个主要版本进入 classpath。问题是,如果 Maven 最终选了旧版本,而你的代码或某个框架需要新版本,就可能出现:

NoSuchMethodError
ClassNotFoundException
NoClassDefFoundError

Maven 的依赖调解规则中,遇到多个版本时会选择距离项目更近的版本,也就是“nearest definition”;如果两个版本深度相同,先声明的依赖优先。官方文档还说明,如果你想保证某个版本,可以在项目 POM 中显式声明该依赖版本。(Apache Maven)


三、常见依赖冲突报错

1. NoSuchMethodError

典型报错:

java.lang.NoSuchMethodError: 
com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V

含义:

运行时加载到了某个类
但这个类里没有当前代码需要调用的方法

常见原因:

编译时使用的是新版本 Jar
运行时加载的是旧版本 Jar

这是典型版本冲突。


2. ClassNotFoundException

java.lang.ClassNotFoundException: com.example.SomeClass

含义:

运行时找不到某个类

常见原因:

依赖没有被打进包
scope 写错
依赖被排除了
运行环境缺少 Jar
容器中依赖和项目依赖不一致

3. NoClassDefFoundError

java.lang.NoClassDefFoundError: com/example/SomeClass

含义:

编译时可能能找到类,但运行时找不到

常见原因:

依赖未打包
依赖 scope 不对
运行环境缺少 Jar
版本冲突导致类不存在

4. ClassCastException

java.lang.ClassCastException: class A cannot be cast to class A

这种看起来很奇怪,两个类名一样还不能转换,通常可能是:

同一个类被不同 ClassLoader 加载
项目和容器里存在重复 Jar
插件或应用服务器自带依赖与项目依赖冲突

四、第一步:用 dependency:tree 查看依赖树

最常用命令:

mvn dependency:tree

Maven Dependency Plugin 官方文档说明,dependency:tree 用来查看当前项目正在构建时解析出来的依赖层级,也就是 Maven 构建过程实际使用的依赖树。(Apache Maven)

输出示例:

[INFO] com.example:demo:jar:1.0.0
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:3.5.15:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:3.5.15:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.19.2:compile
[INFO] +- com.example:some-sdk:jar:1.0.0:compile
[INFO] |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.13.5:compile

这种情况下就要看最终 Maven 选择了哪个版本,以及旧版本是从哪个依赖传递进来的。


五、只查看某个依赖:-Dincludes

如果依赖树太长,可以用 -Dincludes 过滤。

例如只看 Jackson:

mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind

只看 Guava:

mvn dependency:tree -Dincludes=com.google.guava:guava

只看 SLF4J:

mvn dependency:tree -Dincludes=org.slf4j

dependency:tree 支持 includesexcludes 参数,过滤格式为 [groupId]:[artifactId]:[type]:[version],各段都支持通配符。(Apache Maven)

常用命令:

mvn dependency:tree -Dincludes=org.slf4j
mvn dependency:tree -Dincludes=ch.qos.logback
mvn dependency:tree -Dincludes=com.fasterxml.jackson.core
mvn dependency:tree -Dincludes=com.google.guava
mvn dependency:tree -Dincludes=io.netty

六、输出到文件方便搜索

项目依赖多时,控制台不好看,可以输出到文件:

mvn dependency:tree -DoutputFile=dependency-tree.txt

官方文档说明,dependency:tree 支持通过 outputFile 将依赖树输出到文件,也支持 text、dot、graphml、tgf、json 等输出格式。(Apache Maven)

例如输出 JSON:

mvn dependency:tree -DoutputType=json -DoutputFile=dependency-tree.json

输出后可以搜索:

jackson
guava
netty
slf4j
logback
tomcat
hibernate

七、看 omitted 信息

可以加:

mvn dependency:tree -Dverbose

它会显示一些被 Maven 省略的依赖节点,例如:

omitted for conflict with 2.17.2
omitted for duplicate

这对判断版本冲突很有帮助。

注意:不同 Maven Dependency Plugin 版本的输出细节可能不同。如果 -Dverbose 输出不明显,可以结合 -Dincludes 或输出文件搜索。


八、Maven为什么会选这个版本?

举一个例子。

依赖关系:

demo
├── A
│   └── C:1.0
└── B
    └── D
        └── C:2.0

这里 C:1.0 离 demo 更近,所以 Maven 可能选择 C:1.0

再比如:

demo
├── A
│   └── C:1.0
└── B
    └── C:2.0

如果两个版本深度相同,则先声明的依赖路径优先。Maven 官方文档将这种规则称为 dependency mediation,也就是通过“最近定义”和“同深度先声明优先”来决定最终版本。(Apache Maven)

所以排查冲突时,要看:

冲突依赖有几个版本
每个版本从哪条路径进来
哪个版本最终生效
最终生效版本是否符合项目预期

九、解决方式一:直接声明需要的依赖版本

如果你明确知道项目应该使用某个版本,可以在当前项目中直接声明它。

例如统一使用 Guava 32.1.3:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

因为它变成了当前项目的直接依赖,路径更近,通常可以覆盖传递依赖中的旧版本。

适合场景:

你确实直接使用了这个依赖
你明确知道应该使用哪个版本
该版本与其他依赖兼容

不适合:

你只是为了压住冲突,随便加一个版本
项目根本不直接使用该依赖
该版本可能破坏其他库兼容性

十、解决方式二:用 dependencyManagement 统一版本

多模块项目更推荐使用 dependencyManagement 统一版本。

父 POM 示例:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.3-jre</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块中可以不写版本:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
</dependency>

Maven 官方文档说明,dependencyManagement 是集中管理依赖信息的机制,尤其适合多个项目或子模块继承同一个父 POM 的场景。(Apache Maven)

注意:

dependencyManagement 不等于真正引入依赖
它只是管理版本
真正引入还要写在 dependencies 里

十一、解决方式三:使用BOM统一依赖版本

Spring Boot 项目常见做法是使用 Spring Boot BOM。

如果使用:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.15</version>
</parent>

Spring Boot 会帮你管理一批常用依赖版本。

如果不使用 parent,也可以导入 BOM:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.5.15</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后依赖可以不写版本:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot 项目不建议随便覆盖 Jackson、Tomcat、Logback、Hibernate、Spring Framework 等核心依赖版本。除非你明确知道为什么要覆盖,以及覆盖后对整个依赖树的影响。


十二、解决方式四:使用 exclusions 排除传递依赖

如果某个依赖传递进来了不需要的旧 Jar,可以用 exclusions 排除。

例如某个 SDK 带进旧版 Guava:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>some-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

查看依赖树:

mvn dependency:tree -Dincludes=com.google.guava:guava

发现:

com.example:some-sdk:jar:1.0.0
\- com.google.guava:guava:jar:18.0

可以这样排除:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>some-sdk</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

然后自己声明需要的版本:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

Maven 官方文档说明,exclusions 是定义在某个具体 dependency 里的,用于排除由该依赖路径传递进来的特定 groupId 和 artifactId;官方也提醒,exclusion 更像最后手段,应该确认到底是哪条依赖路径引入了不想要的传递依赖。(Apache Maven)


十三、不要滥用 exclusions

exclusions 很有用,但不能乱用。

不建议这样:

看到冲突就排除
不知道谁需要这个依赖也排除
把一堆依赖全部排掉
复制网上的 exclusions 不理解原因

排除依赖前要确认:

1. 这个依赖是谁带进来的
2. 项目是否真的不需要它
3. 排除后有没有替代版本
4. 排除后是否影响原依赖的功能
5. 测试是否覆盖相关功能

错误排除可能导致:

ClassNotFoundException
NoClassDefFoundError
某些功能运行到一半才报错

十四、解决方式五:升级上游依赖

有些冲突最好不要靠排除解决,而是升级上游依赖。

例如:

old-sdk 1.0 -> guava 18.0
old-sdk 2.0 -> guava 32.x

如果可以升级 old-sdk,优先升级它,而不是强行排除里面的传递依赖。

适合升级上游依赖的场景:

上游依赖已有兼容新版本
旧版本存在安全漏洞
旧版本不支持当前 JDK
旧版本与 Spring Boot 3 / 4 不兼容

升级后仍要执行:

mvn dependency:tree
mvn clean test
mvn clean package

十五、解决方式六:排查 scope 是否写错

Maven 的 scope 也会导致运行时依赖缺失。

常见 scope:

scope含义常见问题
compile默认,编译和运行都需要最常用
provided编译需要,运行由容器提供打包后可能没有
runtime编译不需要,运行需要数据库驱动常见
test只测试使用主程序运行时没有

典型错误:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
    <scope>test</scope>
</dependency>

这样正式运行时可能找不到数据库驱动。

如果你用 Spring Boot 打 fat jar,大多数业务依赖不应该随便写成 provided


十六、解决方式七:排查重复日志依赖

日志依赖冲突很常见。

典型现象:

SLF4J: Class path contains multiple SLF4J bindings
LoggerFactory is not a Logback LoggerContext
NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder

常见冲突:

slf4j-log4j12
log4j-to-slf4j
log4j-slf4j-impl
logback-classic
jul-to-slf4j

先看依赖树:

mvn dependency:tree -Dincludes=org.slf4j
mvn dependency:tree -Dincludes=ch.qos.logback
mvn dependency:tree -Dincludes=org.apache.logging.log4j

Spring Boot 默认日志体系通常是:

spring-boot-starter-logging
logback-classic
slf4j

如果你没有明确切换 Log4j2,不建议乱加日志实现依赖。


十七、解决方式八:排查 Jackson 版本冲突

Spring Boot 项目中 Jackson 冲突也很常见。

典型报错:

NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.xxx
ClassNotFoundException: com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
InvalidDefinitionException

排查:

mvn dependency:tree -Dincludes=com.fasterxml.jackson.core
mvn dependency:tree -Dincludes=com.fasterxml.jackson.datatype
mvn dependency:tree -Dincludes=com.fasterxml.jackson.module

Spring Boot 项目优先使用 Spring Boot 管理的 Jackson 版本,不建议手动指定:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>某个随手写的版本</version>
</dependency>

除非有明确安全修复或兼容要求,并且完整测试过。


十八、解决方式九:排查 Netty 版本冲突

使用这些技术时,Netty 冲突很常见:

Spring WebFlux
Reactor Netty
Redisson
Dubbo
Elasticsearch Client
gRPC
RocketMQ
Netty自定义通信

排查:

mvn dependency:tree -Dincludes=io.netty

常见问题:

NoSuchMethodError
ClassNotFoundException
Native transport 加载失败
不同组件依赖不同 Netty 小版本

处理方式:

优先让框架 BOM 管理版本
不要手动混用多个 Netty 版本
升级上游组件
必要时用 dependencyManagement 统一版本

十九、解决方式十:用 effective-pom 看最终POM

有时候你看当前 pom.xml 看不出问题,因为版本来自:

父POM
dependencyManagement
Spring Boot BOM
公司父工程
profile

可以执行:

mvn help:effective-pom

输出到文件:

mvn help:effective-pom -Doutput=effective-pom.xml

然后搜索:

dependencyManagement
jackson
guava
netty
slf4j
spring-boot-dependencies

effective-pom 能帮你看到 Maven 合并父 POM、profiles、dependencyManagement 后的最终 POM。


二十、用 dependency:analyze 找未声明和未使用依赖

可以执行:

mvn dependency:analyze

Maven Dependency Plugin 官方文档说明,dependency:analyze 会进行字节码分析,用于发现缺失依赖和未使用依赖;dependency:analyze-dep-mgt 则可以检查最终解析依赖与 dependencyManagement 中配置之间的不匹配。(Apache Maven)

常见输出可能包括:

Used undeclared dependencies
Unused declared dependencies

含义:

Used undeclared dependencies:
代码里用了这个依赖,但 pom.xml 没直接声明,可能是靠传递依赖带进来的

Unused declared dependencies:
pom.xml 声明了依赖,但代码没有直接使用

不要机械删除所有 “Unused declared dependencies”,因为有些依赖可能是运行时、反射、SPI、注解处理或框架自动加载用到的。


二十一、Spring Boot项目的推荐处理方式

Spring Boot 项目优先遵守这个顺序:

1. 使用 spring-boot-starter-parent 或 spring-boot-dependencies BOM
2. 不随便写 Spring Boot 已管理依赖的 version
3. 用 dependency:tree 找冲突来源
4. 优先升级第三方 Starter
5. 必要时用 exclusions 排除明确不需要的传递依赖
6. 最后才用 dependencyManagement 覆盖核心依赖版本

不推荐:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>随便指定一个版本</version>
</dependency>

Spring Boot 项目中,Spring Framework、Jackson、Tomcat、Logback、Hibernate 等核心版本应该尽量由 Spring Boot 管理。


二十二、多模块项目怎么统一依赖?

多模块项目建议在父 POM 中统一管理版本。

父 POM:

<properties>
    <jackson.version>2.19.2</jackson.version>
    <guava.version>32.1.3-jre</guava.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
</dependency>

这样可以避免每个子模块各写各的版本。


二十三、常见案例:Guava版本冲突

报错

java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument

排查

mvn dependency:tree -Dincludes=com.google.guava:guava

可能看到:

com.example:demo
+- com.example:old-sdk:1.0
|  \- com.google.guava:guava:18.0
\- com.example:new-sdk:2.0
   \- com.google.guava:guava:32.1.3-jre

解决思路

如果项目需要新版 Guava:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.3-jre</version>
        </dependency>
    </dependencies>
</dependencyManagement>

如果旧 SDK 带入的 Guava 完全不需要,也可以排除:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>old-sdk</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

二十四、常见案例:Jackson版本冲突

报错

java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.xxx

排查

mvn dependency:tree -Dincludes=com.fasterxml.jackson.core

可能原因

手动指定了 jackson-databind 旧版本
某个 SDK 带入旧版 Jackson
Spring Boot 管理的版本被覆盖
不同 Jackson 模块版本不一致

解决建议

Spring Boot 项目优先删除手写 Jackson version
让 Spring Boot BOM 管理 Jackson
如果确实要升级,尽量整组统一 jackson-core、jackson-databind、jackson-annotations、jackson-datatype-jsr310

二十五、常见案例:日志依赖冲突

报错

SLF4J: Class path contains multiple SLF4J bindings

排查

mvn dependency:tree -Dincludes=org.slf4j
mvn dependency:tree -Dincludes=ch.qos.logback
mvn dependency:tree -Dincludes=org.apache.logging.log4j

解决思路

确认项目使用 Logback 还是 Log4j2
不要同时引入多个日志实现
Spring Boot 默认使用 Logback
如果切换 Log4j2,要按 Spring Boot 推荐方式排除默认 logging starter

二十六、完整排查清单

遇到 Maven 依赖冲突,按下面步骤来:

1. 保存完整报错,不要只看第一行
2. 判断是 NoSuchMethodError、ClassNotFoundException 还是 NoClassDefFoundError
3. 找到报错中的类名或包名
4. 判断它属于哪个依赖
5. 执行 mvn dependency:tree
6. 使用 -Dincludes 过滤目标依赖
7. 查看是否存在多个版本
8. 找到冲突依赖的引入路径
9. 判断 Maven 最终选择的版本
10. 优先使用 BOM 或 dependencyManagement 统一版本
11. 必要时使用 exclusions 排除旧版本
12. 检查 scope 是否错误
13. 执行 mvn help:effective-pom 查看最终版本
14. 执行 mvn dependency:analyze 辅助检查
15. 执行 mvn clean test / mvn clean package 验证
16. 在和生产一致的环境中运行验证

二十七、常用命令汇总

# 查看完整依赖树
mvn dependency:tree

# 查看某个依赖
mvn dependency:tree -Dincludes=com.google.guava:guava

# 查看某个 groupId 下所有依赖
mvn dependency:tree -Dincludes=com.fasterxml.jackson.core

# 输出到文件
mvn dependency:tree -DoutputFile=dependency-tree.txt

# 输出 JSON
mvn dependency:tree -DoutputType=json -DoutputFile=dependency-tree.json

# 查看最终 POM
mvn help:effective-pom

# 输出最终 POM 到文件
mvn help:effective-pom -Doutput=effective-pom.xml

# 分析未声明和未使用依赖
mvn dependency:analyze

# 检查 dependencyManagement 与最终解析结果
mvn dependency:analyze-dep-mgt

# 清理并测试
mvn clean test

# 清理并打包
mvn clean package

二十八、常见问题FAQ

1. Maven依赖冲突一定要用 exclusions 吗?

不一定。优先考虑:

升级上游依赖
使用 BOM
用 dependencyManagement 统一版本
直接声明需要的依赖版本

exclusions 应该在明确知道哪条路径引入了不需要的依赖后再使用。


2. dependencyManagement 会自动引入依赖吗?

不会。

dependencyManagement 只管理版本,不会自动把依赖加入项目。真正引入依赖仍然要写在 <dependencies> 里。


3. 为什么我明明写了版本,Maven还是用了别的版本?

可能是:

父POM或BOM管理了版本
dependencyManagement覆盖了版本
多模块父子POM继承导致最终版本变化
profile影响了依赖

执行:

mvn help:effective-pom

查看最终 POM。


4. NoSuchMethodError一定是依赖冲突吗?

大概率和版本不匹配有关,但不一定只来自 Maven。

也可能是:

服务器旧 Jar 没清理
容器自带依赖冲突
IDEA 和打包运行 classpath 不一致
插件或 ClassLoader 隔离问题

先用 dependency:tree 排查项目依赖,再检查运行环境。


5. Spring Boot项目能不能手动指定Jackson版本?

可以,但不建议随便指定。

Spring Boot 已经管理了一组兼容版本。除非有安全漏洞修复或明确兼容需求,否则优先使用 Boot 管理的版本。


6. IDEA里怎么查看Maven依赖冲突?

可以在 Maven 工具窗口查看依赖树,也可以使用依赖图功能。但最终仍建议用命令:

mvn dependency:tree

命令行结果更适合复制、搜索、记录和排查。


7. 删除 .m2 仓库能解决依赖冲突吗?

通常不能。

删除 .m2 主要解决本地缓存损坏或下载失败,不解决版本选择和传递依赖冲突。

依赖冲突要看:

dependency:tree
dependencyManagement
exclusions
BOM
scope

二十九、最终总结

Maven 依赖冲突排查的核心不是“猜”,而是看清楚依赖树。

记住这几个规则:

Maven会自动引入传递依赖
多个版本冲突时,Maven会按依赖调解规则选择最终版本
dependency:tree可以看到依赖来源
dependencyManagement用于统一版本
exclusions用于排除特定传递依赖
Spring Boot项目优先使用官方BOM管理版本
不要滥用exclusions
不要随便覆盖核心依赖版本

推荐排查命令:

mvn dependency:tree
mvn dependency:tree -Dincludes=目标groupId:artifactId
mvn help:effective-pom
mvn dependency:analyze

只要能回答这三个问题,依赖冲突基本就能解决一大半:

最终生效的是哪个版本?
这个版本是从哪条依赖路径来的?
我应该统一版本、升级上游依赖,还是排除传递依赖?

三十、相关文章

Maven 依赖下载失败可以看:

Maven Could not transfer artifact 下载失败解决:settings.xml、国内镜像、本地缓存与代理排查

Maven 国内镜像配置可以看:

Maven国内镜像settings.xml配置大全:阿里云、腾讯云、华为云、清华源

Maven 编译器错误可以看:

No compiler is provided in this environment解决办法

JDK 下载地址可以看:

各版本JDK镜像下载地址:JDK8 / 11 / 17 / 21 / 25 / 26

Spring Boot 与 JDK 兼容可以看:

Spring Boot与JDK版本兼容表

完整 Java 环境配置专题:

Java开发环境配置专题


更新记录

2026-07-10:
- 创建 Maven 依赖冲突排查教程
- 增加 dependency:tree 使用方法
- 增加 includes / outputFile / outputType 示例
- 增加 dependencyManagement、BOM、exclusions 处理方式
- 增加 Guava、Jackson、日志、Netty 常见冲突案例
- 增加 effective-pom、dependency:analyze 排查命令
- 增加 Spring Boot 项目依赖版本建议