本指南解释了如何在 Gradle 中降级传递性依赖,当您的项目由于 API 兼容性、bug 或其他约束而需要旧版本时。
选项 1:强制执行依赖的严格版本
Gradle 允许您对依赖项强制执行严格版本,确保所选版本不会被传递性依赖升级。
步骤 1:设置严格版本
假设一个项目依赖于 HttpClient,它引入了 Commons Codec 1.10,但您的项目需要 Commons Codec 1.9
> Task :dependencies
------------------------------------------------------------
Root project 'how_to_downgrade_transitive_dependencies'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.httpcomponents:httpclient:4.5.4
| +--- org.apache.httpcomponents:httpcore:4.4.7
| +--- commons-logging:commons-logging:1.2
| \--- commons-codec:commons-codec:1.10
\--- commons-codec:commons-codec -> 1.10
您可以通过设置严格版本约束来强制执行所需的版本
dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.4")
implementation("commons-codec:commons-codec") {
version {
strictly("1.9")
}
}
}
dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.4")
implementation("commons-codec:commons-codec") {
version {
strictly("1.9")
}
}
}
运行 ./gradlew dependencies --configuration runtimeClasspath
可以展示结果
> Task :dependencies
------------------------------------------------------------
Root project 'how_to_downgrade_transitive_dependencies'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.httpcomponents:httpclient:4.5.4
| +--- org.apache.httpcomponents:httpcore:4.4.7
| +--- commons-logging:commons-logging:1.2
| \--- commons-codec:commons-codec:1.10 -> 1.9
\--- commons-codec:commons-codec:{strictly 1.9} -> 1.9
关于严格版本的重要注意事项
-
严格版本的行为类似于强制,这意味着它会覆盖传递性依赖。
-
如果其他依赖项需要更高的版本,Gradle 将会失败并出现解析错误。
-
使用版本范围而不是绝对严格版本以提供灵活性。
步骤 2:设置严格版本范围
除了锁定到单个版本,还可以定义一个严格范围
dependencies {
implementation("commons-codec:commons-codec") {
version {
strictly("[1.9,2.0[") // Allows versions >=1.9 and <2.0
prefer("1.9") // Prefers 1.9 but allows newer versions in range
}
}
}
dependencies {
implementation("commons-codec:commons-codec") {
version {
strictly("[1.9,2.0[") // Allows versions >=1.9 and <2.0
prefer("1.9") // Prefers 1.9 but allows newer versions in range
}
}
}
如果其他依赖项需要 1.10,只要它在指定范围内,Gradle 就可以解析它而不会失败。
> Task :dependencies
------------------------------------------------------------
Root project 'how_to_downgrade_transitive_dependencies'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.httpcomponents:httpclient:4.5.4
| +--- org.apache.httpcomponents:httpcore:4.4.7
| +--- commons-logging:commons-logging:1.2
| \--- commons-codec:commons-codec:1.10 -> 1.9
\--- commons-codec:commons-codec:{strictly [1.9,2.0[; prefer 1.9} -> 1.9
选项 2:在配置层面强制指定版本
如果严格依赖限制性过强,您可以使用 resolutionStrategy.force()
为整个配置强制指定特定版本。
步骤 1:为整个构建强制指定版本
configurations {
compileClasspath {
resolutionStrategy.force("commons-codec:commons-codec:1.9")
}
}
dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.4")
}
configurations {
compileClasspath {
resolutionStrategy.force("commons-codec:commons-codec:1.9")
}
}
dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.4")
}
运行 ./gradlew dependencies --configuration compileClasspath
可以展示结果
> Task :dependencies
------------------------------------------------------------
Root project 'how_to_downgrade_transitive_dependencies'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
\--- org.apache.httpcomponents:httpclient:4.5.4
+--- org.apache.httpcomponents:httpcore:4.4.7
+--- commons-logging:commons-logging:1.2
\--- commons-codec:commons-codec:1.10 -> 1.9
这确保了始终使用 Commons Codec 1.9,即使传递性依赖请求了更新的版本。
总结
回顾这两种选项
方法 | 行为 |
---|---|
1. 严格版本 ( |
该版本被强制执行,但如果存在冲突,可能会触发解析失败。 |
2. 强制版本 ( |
该版本在配置层面被强制应用,覆盖所有其他约束。 |
总结如下
-
如果您需要强制使用旧版本并希望控制兼容性,请使用严格版本。
-
使用带有首选版本的版本范围以获得一定的灵活性。
-
当您需要在没有严格约束的情况下覆盖传递性依赖时,请在配置层面使用
force()
。