【gradle 8 升级系列】 force 替换为constraints
文章目录
引言
在Gradle 8中,引入了一种名为"constraints"的新功能,用于管理和解决依赖项之间的冲突。通过使用"constraints",您可以更精确地指定依赖项的版本范围,并确保它们与其他依赖项兼容。
升级传递依赖项的版本
直接依赖与依赖约束
一个组件可能有两种不同类型的依赖关系:
- 直接依赖:直接由组件所需。直接依赖也称为一级依赖。例如,如果你的项目源代码需要Guava,则应将Guava声明为直接依赖。
- 传递依赖:由于其他依赖项的需要,组件需要它们。
对于依赖管理的问题通常涉及到传递依赖。开发人员经常错误地通过添加直接依赖来解决传递依赖问题。为了避免这种情况,Gradle提供了依赖约束constraints的概念。
在传递依赖项上添加约束constraints
依赖约束允许您定义构建脚本中声明的依赖项和传递依赖项的版本或版本范围。这是表达应用于配置的所有依赖项的约束条件的首选方法。
当Gradle尝试解析模块版本的依赖关系时,将考虑到该模块的所有依赖声明、所有传递依赖项以及所有依赖约束。选择满足所有条件的最高版本。
如果找不到这样的版本,Gradle将失败并显示冲突的声明。
如果出现这种情况,您可以调整依赖项或依赖约束的声明,或者根据需要对传递依赖项进行其他调整。与依赖声明类似,依赖约束的声明也受配置的影响,并且可以有选择地为构建的某些部分定义。如果依赖约束影响了解析结果,则任何类型的依赖解析规则仍然可以在此之后应用。
示例
以下是如何使用"constraints"的示例:
示例1:定义依赖约束
dependencies {
implementation 'org.apache.httpcomponents:httpclient'
constraints {
implementation('org.apache.httpcomponents:httpclient:4.5.3') {
because 'previous versions have a bug impacting this application'
}
implementation('commons-codec:commons-codec:1.11') {
because 'version 1.9 pulled from httpclient has bugs affecting this application'
}
}
}
在该示例中,依赖声明中省略了所有版本信息。相反,版本信息在约束块中定义。只有当commons-codec作为传递依赖项引入时,才会考虑到commons-codec:1.11的版本定义,因为在项目中未将commons-codec定义为依赖项。否则,该约束不起作用。依赖约束还可以定义丰富的版本约束,并支持严格版本以强制执行一个版本,即使它与传递依赖项定义的版本相矛盾(例如,如果需要降级版本)。
依赖约束只在使用Gradle模块元数据时才会被发布。这意味着如果使用Gradle进行发布和消费,则完全支持它们(即,在使用Maven或Ivy消费模块时,它们将"丢失")。依赖约束本身也可以以传递方式添加。
示例2
- 在项目的build.gradle文件中,添加一个"constraints"块,用于定义依赖项的约束:
dependencies {
constraints {
implementation("com.google.protobuf:protobuf-java:${protobufJavaVersion}")
}
}
在这个例子中,我们使用${protobufJavaVersion}
变量来指定依赖项的版本。您可以根据您的实际情况替换该变量。
- 通过定义约束,Gradle将尝试解决依赖关系并选择与其他依赖项兼容的最新版本。如果存在多个候选版本符合约束条件,Gradle将选择最新的版本作为解决方案。如果找不到满足所有约束的版本,Gradle将报告冲突并提示您解决问题。
- 可以使用命令
./gradlew dependencies --constraints
来查看应用约束后的依赖关系图。
注意事项
使用"constraints"需要遵循一些最佳实践:
- 约束应该尽可能明确,以便减少潜在的冲突和不确定性。
- 及时更新约束以使用最新的稳定版本,并保持与其他依赖项的兼容性。
- 了解项目中所有依赖项的约束关系,以避免潜在的冲突或不一致。