3. 使用本地文件系统作为缓存仓库:配置 repositories.localCache、目录创建与权限
在离线环境下,Gradle 必须通过预先填充的本地缓存来提供所有依赖。使用 repositories.localCache 配置可以将一个预先准备好的本地文件夹注册为唯一的依赖仓库,完全绕过远程仓库调用。本章从原理到实施详细讲解如何设置、调试并加固该缓存仓库。
3.1 原理:本地文件系统缓存的工作方式
Gradle 的依赖解析生命周期中,仓库列表的优先级由声明顺序决定。当使用 repositories.localCache 时,Gradle 会以与 Maven 仓库相同的目录结构 <groupId>/<artifactId>/<version>/<artifact>-<version>.pom 扫描本地路径。离线模式下,若该仓库中找不到依赖,则整个构建立即失败,不会回退到任何远程仓库。
核心行为:
- 仓库类型:
ivy或maven风格的本地目录 - 元数据要求:必须包含
.pom或ivy.xml文件(视仓库类型而定) - 离线开关:
--offline标志阻止任何远程访问,但不影响本地仓库的读取
3.2 配置 repositories.localCache
repositories.localCache 是 Gradle 提供的一个便捷方法,用于添加基于本地文件系统的 Maven 或 Ivy 仓库。常用配置位置在 settings.gradle 中,可以确保该仓库对项目中的所有子项目生效。
最佳实践: 在 settings.gradle 中使用 pluginManagement.repositories 和 dependencyResolutionManagement.repositories 同时配置本地缓存,以覆盖插件和依赖两部分。
配置示例(settings.gradle):
dependencyResolutionManagement {
repositories {
localCache {
// 指定本地缓存目录的路径
directory = file("/opt/gradle-offline-cache")
// 可选:设置仓库类型,默认自动检测
// type = "maven"
}
}
}
pluginManagement {
repositories {
localCache {
directory = file("/opt/gradle-offline-cache")
}
}
}
配置参数说明:
| 属性 | 描述 | 必需 |
|---|---|---|
directory | 本地文件系统缓存目录的路径 | 是 |
type | 仓库格式("maven" 或 "ivy"),默认自动从目录结构推断 | 否 |
name | 仓库逻辑名称,用于日志输出区分 | 否 |
3.3 目录创建与权限设置
缓存目录必须在构建开始前存在且可读写。需要特别注意 Linux 环境下由 Jenkins、CI 或容器执行的构建,运行用户通常不是 root。
创建目录(Linux / macOS):
mkdir -p /opt/gradle-offline-cache
chown -R gradle:gradle /opt/gradle-offline-cache
chmod 755 /opt/gradle-offline-cache
创建目录(Windows):
mkdir C:\gradle-offline-cache
icacls C:\gradle-offline-cache /grant "gradle:(OI)(CI)F"
权限验证命令:
# Linux
ls -ld /opt/gradle-offline-cache
# 输出类似:
# drwxr-xr-x 2 gradle gradle 4096 Apr 1 10:00 /opt/gradle-offline-cache
# Windows
icacls C:\gradle-offline-cache
3.4 调试与验证
配置完成后,可以通过 Gradle 的依赖报告或详细日志确认是否使用了本地缓存。
方法一:查看依赖报告
gradle dependencies --offline
方法二:打开仓库解析日志
gradle build --offline --info | grep "localCache"
预期日志输出示例:
2025-04-01T10:00:00.000+0000 [INFO] [org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver]
Using localCache repository at /opt/gradle-offline-cache for artifact com.example:my-lib:1.0.0
如果看到 Could not find artifact ... in localCache,则说明缓存目录中缺少该依赖的 POM 和 JAR 文件。
3.5 常见错误与解决方案
| 错误信息 | 可能原因 | 解决方案 |
|---|---|---|
Directory /path/to/cache does not exist | 目录未创建或路径错误 | 确认目录存在且 settings.gradle 中路径为路径 |
Permission denied | 运行 Gradle 的用户没有读写权限 | 执行 chmod 755 并修改目录所有者 |
No cached version of ... available for offline mode | 本地缓存中缺少该依赖 | 在在线环境中使用 gradle build --no-daemon --build-cache 预填充缓存后重新打包 |
Cannot change strategy of configuration ... after it has been resolved | 在多项目构建中仓库配置顺序错误 | 确保 dependencyResolutionManagement.repositories 在所有 build.gradle 之前定义 |
3.6 性能与稳定性优化
- 使用固态硬盘(SSD): 缓存目录放在 SSD 上可显著减少依赖解析时的 I/O 延迟。
- 避免符号链接: 缓存目录应使用真实物理路径,符号链接可能导致 Gradle 解析器误判仓库可达性。
- 定期清理过期缓存: 使用 cron job 或构建后脚本删除超过 N 天的缓存文件,防止磁盘空间爆炸。
- 副本保护: 在分布式 CI 环境中,将缓存目录挂载为只读共享卷(NFS 或 SAN),确保所有节点使用一致快照。
重要: 如果多个构建并发访问同一个本地缓存目录,务必使用文件锁或只读挂载以避免文件损坏。Gradle 本身对同目录并发读取是安全的,但写入(例如并行预填充)可能导致元数据不一致。