Gradle 7.0+ 必须在 settings.gradle.kts 的 dependencyResolutionManagement 块中统一配置仓库,且需位于 include 之后、pluginManagement 之前;Version Catalog 需各模块显式启用并确保路径和条目定义正确;多模块需保证项目路径末尾名称全局唯一;includeBuild 时应避免与远程同名版本冲突。

settings.gradle里没配dependencyResolutionManagement,跨项目就找不到依赖
Gradle 7.0+ 默认把依赖仓库配置从 build.gradle 移到了 settings.gradle 的 dependencyResolutionManagement 块里。如果只在某个子模块的 build.gradle 里写了 mavenCentral(),其他模块根本看不到——它们压根不会去读那个文件。
常见错误现象:
- 子模块 A 能正常编译,子模块 B 报
Could not resolve com.example:lib:1.2.3 - IDE 显示依赖已导入,但编译时报
package does not exist - 执行
./gradlew dependencies时,B 模块的依赖树里完全不出现该库
正确做法是统一在 settings.gradle.kts 顶层声明:
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
maven { url = uri("https://your-private-repo.com") }
}
}
注意:这个块必须在 include 之后、任何 pluginManagement 之前(顺序错会导致仓库未生效)。
libs.versions.toml 跨项目引用时路径或语法写错
Version Catalog 是集中管理版本的好办法,但它不是“全局自动可见”的。你得确保每个用到 libs 的模块都显式启用了 catalog 插件,并且路径指向正确。
容易踩的坑:
- 只在根
build.gradle.kts里加了enableFeaturePreview("VERSION_CATALOGS"),但子模块没加 —— 子模块里libs.xxx直接报 unresolved reference -
libs.versions.toml放在gradle/libs.versions.toml,但settings.gradle.kts里写成了versionCatalogs { create("libs") { from(files("../libs.versions.toml")) } }(路径少了一级gradle/) - 在 toml 文件里写了
spring-boot = { version = "3.3.4", ... },但在 build 中用了implementation(libs.spring.boot.starter.web)—— 实际上要先定义spring-boot-starter-web这个条目,不能靠嵌套自动推导
多模块同名导致 project(':common') 解析歧义
Gradle 内部对项目路径的解析,在某些场景下会优先匹配短名称(即冒号后最后一段),而不是完整路径。比如同时存在 :core:common 和 :app:common,当你在某个模块里写 implementation(project(":common")),Gradle 可能随机选一个,或者直接报错 Project with path ':common' could not be found。
这不是 bug,而是设计限制。解决方式很实在:
- 所有
include的路径必须保证末尾名称全局唯一,例如改include("core:common")和include("app:common-ui") - 跨模块依赖必须写完整路径:
implementation(project(":core:common")),别图省事省略 - 避免在
settings.gradle里用includeFlat—— 它会彻底抹掉层级,加剧名称冲突风险
复合构建 includeBuild 后,本地模块被远程同名版本覆盖
用 includeBuild("../my-logging-lib") 引入本地源码工程时,如果远程仓库(比如 Maven Central)也存在同 group/id/version 的发布包,Gradle 默认优先使用远程二进制,而不是你本地改的代码。
结果就是:你改了 my-logging-lib 里的日志格式,但主项目运行时还是旧输出 —— 因为它实际拉的是缓存里的远程 jar。
绕过方法只有两个:
- 临时禁用远程仓库:在
dependencyResolutionManagement里注释掉mavenCentral(),仅保留includeBuild所需的本地源 - 强制替换:在主项目的
build.gradle.kts里加configurations.all { resolutionStrategy { force("com.example:my-logging-lib:1.0.0-SNAPSHOT") } },但要注意这会覆盖所有 transitive 使用该库的地方
最稳妥的做法其实是把本地模块的 version 改成带 -local 后缀(如 1.0.0-local),并在 catalog 或依赖声明里明确指定该版本 —— 避免和远程发布版产生坐标重叠。
跨项目读取配置真正难的不是语法,而是 Gradle 在初始化阶段就锁定了作用域边界。一旦 settings.gradle 没把策略铺平,后续所有 build.gradle 都是在各自孤立的上下文中运行。很多人调试半天才发现,问题不在代码里,而在那个开头就被忽略的 settings 文件里。


















