DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
晚安云;香港 CN2 ¥15/月
雨云;给项目一台云服务器

Gradle 无输出退出 1:检查 included build 的写权限

Gradle 9.7.1、9.8.2 引入可读却不可写的 build 时,可能静默退出 1。核对被引入工程自己的 .gradle 状态目录,在受控可写副本构建,并以退出码判断结果。

主工程能写,执行 ./gradlew help 却直接退出 1,stdout、stderr 都没有常见的 FAILURE 段落;加 --stacktrace 也没内容。若 settings 通过 includeBuild 引入另一份目录,检查运行构建的账号是否也能写入那份构建的项目状态目录。

Gradle 9.7.1、9.8.2 在 Ubuntu 24.04、Temurin 21.0.12 的具体组合中有这条表现:被引入构建可读、不可写时,复合构建静默失败;把它单独作为构建入口运行,则出现 .gradle/.../fileHashes 无法创建的正常错误。

included build 仍有自己的项目状态

Gradle 的用户主目录与项目根目录都可能保存缓存。项目本地的 .gradle 用于该工程的状态,不会因为消费方目录可写,就自动转移到消费方。

复合构建中的各个 build 又有自己的配置边界。主工程能创建自己的 .gradle,不表示相邻 includeBuild 目录也满足要求;将 GRADLE_USER_HOME 换到新位置,也不能据此认定项目本地状态目录已经改变。

先按真正执行 Wrapper 的身份核对 includeBuild 路径、挂载是否只读、已有状态目录的所有者及权限。相对 includeBuild 路径以 settings 所在目录为基准,不以终端偶然停留的位置为基准。不要只检查工作站上当前登录用户能否在 IDE 里编辑源码。

在可写的自有工作副本中构建

目录本来应由当前构建账号管理时,按项目既有权限规则修正需要的写入范围,并保留所有者与挂载配置。不要递归开放所有用户写权限,也不要让 CI 以管理员身份访问共享源码来掩盖权限不符。

如果上游源码刻意以只读方式提供,可在当前任务拥有的可写工作副本中执行它,再让主工程指向这份副本。例如 settings.gradle.kts 的引用片段可以是:

includeBuild("../inc-writable")

inc-writable 是示例名,不是要求创建固定目录。副本应保持经过审定的源码、构建文件及必要相对布局,不能从未知来源重新下载另一版来替代;涉及相对资源、依赖替换或脚本路径时,要一起检查。不要修改其他任务正在使用的共享工作树。

有些项目会单独配置缓存与输出位置。应按实际构建约定验证每个 included build 的最终路径,而不是给主命令增加一个目录参数后,就假定所有内部写入都已搬走。

无输出也要检查退出状态

诊断材料需要同时保存 Wrapper 版本、命令、进程退出码、两个输出流和对应 daemon 日志。Success[BuildActionResult] 这样的内部消息不等于用户构建成功;本题的可见结果仍是退出 1,自动化不能因为日志里没出现 BUILD FAILED 就继续发布。

在隔离工作副本分别执行原复合入口与 included build 的独立入口,确认所需目录可写、原任务完成且产物来自正确源码。修正后再恢复正常流水线;旧日志仍可保留定位静默报告缺口,不需要为一条错误停止共享 daemon 或清空所有 Gradle 缓存。