Gradle 说依赖解析失败,lenient 文件列表却仍包含它的 JAR
Gradle 的依赖替换失败边曾继续贡献 lenient 产物,造成失败列表与 JAR 集合矛盾。9.8.1 包含失败边处理,验收时仍需保留并修正真实规则错误。
Gradle 的解析结果已经将某个依赖标成 unresolved,宽容模式的文件列表却仍包含它以及传递依赖,可以检查失败是否发生在 eachDependency 或 dependency substitution 规则中。lenient 允许继续观察已解析部分,不应把失败的那条边当成正常连接。
Gradle 9.8.0 有一项具体回归:替换规则的失败状态移到 dependency edge 后,取得目标组件的逻辑仍只检查 selector 的失败。规则已抛错,这条边却继续接入请求的目标及其子图,造成失败标记与产物列表不一致。它不是“仓库偶尔慢”或“同一个包应该强制统一版本”的问题。
定位时保留原来抛错的规则、配置名以及所请求模块。可以先沿实际配置查看解析关系:
./gradlew dependencyInsight --dependency <失败模块> --configuration <实际配置>
尖括号内容需要替换。接着比较项目已有的宽容视图与 resolutionResult:
def view = configuration.incoming.artifactView {
lenient = true
}
def result = configuration.incoming.resolutionResult
这里 configuration 指项目实际用于解析的 Configuration,而不是要原样创建一个新配置。记录宽容视图的文件及图中 unresolved 依赖,尤其看抛异常的规则目标是否仍贡献 JAR。默认严格解析可能直接抛出原错误,无法观察同一个宽容视图结果。
Gradle 9.8.1 包含修复:目标组件查询先检查 edge 自己的 substitutionFailure,失败边不再贡献目标子图。可在项目分支更新 wrapper,保留原依赖与规则完成比较:
./gradlew :wrapper --gradle-version=9.8.1
./gradlew :wrapper
./gradlew --version
wrapper 更新要符合项目 Java、插件和构建工具约束;第一遍更新配置,第二遍更新 wrapper 文件后再核实际版本。不要为消除这个症状撤掉原业务解析规则,或直接把失败产物重新拼进 classpath。
修复没有让真正抛异常的规则变成成功。若某条规则意在替换模块,却因为代码错误、缺少条件或不合法目标失败,仍必须处理它;不能把宽容模式当成构建可以安全使用全部文件的保证。
验收可以保留一个能正常解析的对照模块,和一条会明确抛错的规则目标。修复后,宽容列表应只包含合法的已解析产物,失败目标及仅由该边引入的子图不应混入;resolutionResult 仍应正确报告原失败。随后恢复或修正真实规则,运行原构建入口,确认正常依赖解析没有被破坏。
缺文件、认证失败、仓库返回错误等其他 unresolved 情况仍需分别排查。这里的版本结论限定为替换规则失败后边与目标组件状态没有同步的回归。


