Gradle默认采用最高版本策略解决依赖冲突,即在多个同库不同版本中自动选择版本号最大的那个,而非按声明顺序或路径远近;该行为受仓库顺序、本地缓存及是否启用强制约束影响。

Gradle 会自动选中一个你没手动指定的依赖版本,根本原因不是“它随便挑”,而是它按规则做了版本决议(version resolution)——而且默认策略是取最高版本。
Gradle 默认用最高版本策略解决冲突
当你声明了两个或多个模块都依赖同一个库(比如 com.fasterxml.jackson.core:jackson-databind),但各自要求不同版本时,Gradle 不会报错或停住,而是直接选一个它认为“最合理”的版本:所有候选版本里数值最大的那个。
- 例如 A 依赖
jackson-databind:2.12.5,B 依赖jackson-databind:2.15.2,最终进 classpath 的就是2.15.2 - 这个行为和 Maven 的“最近优先”完全不同,容易让人误以为“谁写在前面谁生效”,其实 Gradle 不看声明顺序
- 只要没显式用
force、constraints或version { strictly 'x' }锁死,这个最高版策略就一直生效
缓存和仓库顺序也会悄悄影响“选中结果”
Gradle 下载依赖前要先解析坐标、查仓库、比对可用版本。如果某个仓库里只有旧版,而另一个有新版,且仓库顺序靠前的那个没提供所需版本,Gradle 就可能 fallback 到后面仓库的更高版——你以为它“随便选”,其实是被仓库配置牵着走。
-
repositories块里的顺序很重要:Gradle 按顺序找,**第一个能返回元数据(POM/Metadata)的仓库胜出** - 本地
.gradle/caches/里如果已有某个版本(哪怕过期),Gradle 默认 24 小时内不会重查远程,可能让你误以为“怎么又用了老版本” - 带
-SNAPSHOT的版本会被强制每 24 小时刷新一次,但普通 release 版本不会,除非加--refresh-dependencies
怎么确认 Gradle 到底选了哪个版本?
光看 build.gradle 文件根本看不出实际生效的是哪个版本,必须查已解析的依赖树。
- 运行
./gradlew dependencies --configuration runtimeClasspath(Java 项目)或implementation对应的 configuration 名 - 在输出里搜目标库名,看它前面有没有
\---或+---,以及是否标了(forced)或(selected) - IDEA 用户可直接打开 Maven Projects 工具窗 → 点开 Dependencies 树,右键某个 jar → Go to Declaration 能跳转到具体 resolved 的 POM
真正难的不是“怎么让它选某个版本”,而是“怎么让所有人(包括 CI、新同事、不同 IDE)看到一致的 resolved 结果”。约束(constraints)和版本锁定文件(gradle.lockfile)不是可选项,是多人协作时避免“在我机器上好好的”这类问题的底线操作。

















