没有锁定的依赖,同一份代码今天和明天可能解析出不同的版本。这篇在可控的本地仓库里验证:动态版本如何漂移、Gradle 的依赖锁怎样固定直接与传递依赖、三种 lockMode 的差别,以及校验文件对被篡改产物的检查。
仓库里只有 lib 1.0 / core 1.0:Maven 版本范围 [1.0,2.0) 解析为 lib:1.0 core:1.0(rc=0);Gradle lock:lib:1.+ 解析为 lib:1.+→1.0 core:[1.0,2.0)→1.0 之后发布了 lib 1.1、core 1.1、core 1.2,什么都没改:Maven [1.0,2.0) 解析为 lib:1.0 core:1.0(本地仓库缓存了仓库元数据,默认一天内不再检查);加 -U 强制更新后解析为 lib:1.1 core:1.2;Gradle 1.+ 加 --refresh-dependencies 解析为 lib:1.+→1.1 core:[1.0,2.0)→1.2 把 Maven 依赖写成固定版本 1.0(加 -U):解析为 lib:1.0 core:1.2(lib 自己的依赖范围 [1.0,2.0) 仍然让传递依赖 core 取最新版)
gradle dependencies --write-locks:rc=0;生成 gradle.lockfile,3 行:lock:core:1.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | lock:lib:1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | empty=annotationProcessor,testAnnotationProcessor 锁文件写好之后解析:lib:1.+→1.1 core:[1.0,2.0)→1.2 再发布 lib 1.2 与 core 1.3(仓库里 lib 有 1.0,1.1,1.2、core 有 1.0,1.1,1.2,1.3),加 --refresh-dependencies 解析:lib:1.+→1.1 core:[1.0,2.0)→1.2(仍然是锁里的版本) gradle dependencies --update-locks lock:lib:rc=0;锁文件变成:lock:core:1.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | lock:lib:1.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | empty=annotationProcessor,testAnnotationProcessor;解析:lib:1.+→1.2 core:[1.0,2.0)→1.2(只更新了 lib,没有传递依赖 core) gradle dependencies --update-locks 'lock:*':锁文件变成:lock:core:1.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | lock:lib:1.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath | empty=annotationProcessor,testAnnotationProcessor
锁文件当前内容:lock:core:1.3 | lock:lib:1.2 (lib 1.2 / core 1.3) DEFAULT:声明与锁一致 compileJava rc=0;新增不在锁文件里的依赖 lock:other:1.0 rc=1(> Could not resolve all files for configuration ':compileClasspath'. / > Resolved 'lock:other:1.0' which is not part of the depend);声明改成 lock:lib:[1.0,1.1](锁里是 lib 1.2)rc=0,解析为 lib:[1.0,1.1]→1.2 core:[1.0,2.0)→1.3;删掉锁文件后 rc=0 STRICT:声明与锁一致 compileJava rc=0;新增不在锁文件里的依赖 lock:other:1.0 rc=1(> Could not resolve all files for configuration ':compileClasspath'. / > Resolved 'lock:other:1.0' which is not part of the depend);声明改成 lock:lib:[1.0,1.1](锁里是 lib 1.2)rc=0,解析为 lib:[1.0,1.1]→1.2 core:[1.0,2.0)→1.3;删掉锁文件后 rc=1(> Could not resolve all dependencies for configuration ':compileClasspath'. / > Locking strict mode: Configuration ':compileClassp) LENIENT:声明与锁一致 compileJava rc=0;新增不在锁文件里的依赖 lock:other:1.0 rc=0;声明改成 lock:lib:[1.0,1.1](锁里是 lib 1.2)rc=0,解析为 lib:[1.0,1.1]→1.2 core:[1.0,2.0)→1.3;删掉锁文件后 rc=0
gradle --write-verification-metadata sha256:rc=0;verification-metadata.xml 里 2 个 component:core:1.3,lib:1.2;sha256 条目 4 个 没有改动时 compileJava:rc=0 篡改了仓库里的 lib-1.2.jar(末尾多一个字节):rc=1;错误:> Dependency verification failed for configuration ':compileClasspath' / One artifact failed verification: lib-1.2.jar (lock:lib:1.2) from repository maven / Open this report for more details: file://<jtmp>/j293a/build/reports/dependency-verification/at-1791202214798/dependency-verification-report.html 还原后 compileJava:rc=0