Gradle 不自动区分 SNAPSHOT 与 release 仓库,是否拉取 SNAPSHOT 取决于所配置仓库 URL 对应的远程服务(如 Nexus)策略;需确保 repositories 块中声明了正确的 SNAPSHOT 仓库地址且顺序靠前,并启用对应仓库的 Snapshot 策略与元数据功能。

Gradle 中 repositories 块不自动区分 SNAPSHOT 和 release
Gradle 本身没有内置的“快照仓库”或“正式仓库”类型标签。它只认 repositories 配置里的 URL 和行为策略,是否拉取 SNAPSHOT 版本,取决于你往哪个 URL 里发布、以及该 URL 对应的远程仓库(如 Nexus / Artifactory)如何配置权限和策略。
换句话说:不是 Gradle 在区分,而是你配置的仓库地址背后的服务在区分。
- 如果你把
https://nexus.example.com/repository/maven-snapshots/加进repositories,那这个地址天然只存 SNAPSHOT 包 - 如果你加的是
https://nexus.example.com/repository/maven-releases/,那它通常禁止上传 SNAPSHOT,也默认不提供 SNAPSHOT 查询能力 - Gradle 只是按顺序请求这些 URL;它不会因为某个依赖带
-SNAPSHOT后缀就自动切到另一个仓库
为什么 build.gradle 里写了两个仓库,但 SNAPSHOT 还是下不到?
常见错误是:只在 buildscript 或 pluginManagement 里配了快照仓库,但项目依赖(implementation 等)用的 repositories 块没配,或者配错了顺序。
Gradle 查找依赖时严格按 repositories 声明顺序扫描,一旦在第一个仓库命中(哪怕只是返回 “404 Not Found”),就不会继续往后查。
- 确保
allprojects { repositories { ... } }或模块级repositories { ... }包含了 SNAPSHOT 仓库 URL - 把 SNAPSHOT 仓库放在 release 仓库前面(尤其当它们同属一个 Nexus 实例的不同 repo 时)
- 检查仓库 URL 是否可访问:
curl -I https://your-nexus/repo/maven-snapshots/org/example/lib/1.0.0-SNAPSHOT/maven-metadata.xml - 确认 Nexus 中该 snapshot 仓库启用了 “Snapshot Deployment Policy: Allow Snapshots”
mavenLocal() 对 SNAPSHOT 的特殊行为
mavenLocal() 是 Gradle 提供的本地仓库别名,指向 ${user.home}/.gradle/caches/modules-2/files-2.1(不是 Maven 的 ~/.m2/repository)。但它对 SNAPSHOT 的处理和远程仓库不同:
- Gradle 默认**不检查本地
mavenLocal()中 SNAPSHOT 的更新时间**——只要本地有1.0.0-SNAPSHOT的 jar,就直接用,不会比对远程是否有新 timestamp 版本 - 这意味着:即使远程已发布
1.0.0-20261019.092345-123.jar,只要本地缓存里有旧的1.0.0-SNAPSHOT,Gradle 就不会重新下载 - 解决办法:要么手动删掉本地缓存中对应路径下的整个目录,要么改用
maven { url "file:///path/to/your/m2" }并配合 Nexus 的 metadata 更新机制
真正起作用的是 Nexus / Artifactory 的仓库策略
你在 Gradle 里写的每个 maven { url "..." },最终都要靠后端仓库服务来响应请求。而 Nexus 这类服务才是决定“哪些版本能被列出、哪些能被下载、哪些被拒绝”的关键。
- SNAPSHOT 仓库必须启用 “Browse Indexes” 和 “Metadata Calculations” 才能让 Gradle 正确解析
maven-metadata.xml中的最新 timestamp 版本 - release 仓库通常禁用 SNAPSHOT 上传,并关闭 metadata 更新,避免污染稳定版本语义
- 如果你用的是 JitPack,它会为 GitHub 分支自动生成 SNAPSHOT 式 URL(如
https://jitpack.io/com/github/user/repo-SNAPSHOT),本质仍是靠服务端动态生成版本列表 - Gradle 7.6+ 开始支持
versionCatalogs,但 catalog 本身也不做 SNAPSHOT 路由,它只是把版本字符串固化下来——若 catalog 里写死lib = "com.example:foo:1.0.0-SNAPSHOT",那每次构建仍会去所有已声明的repositories查
最易被忽略的一点:Nexus 里一个仓库的 “Repository Type”(proxy/hosted/group)和 “Version Policy”(Release / Snapshot / Mixed)必须匹配你的使用意图。配错一个下拉选项,Gradle 就永远看不到那个 SNAPSHOT。










