Gradle 7.0 的新增功能
Gradle 7.0 是 Gradle 在构建自动化和开发者生产力演进过程中的下一步。以下是从 Gradle 6.0 到 7.0 的有趣变化。
Gradle 7.0…
- 在执行增量构建时运行速度更快。
- 通过验证构建依赖项的完整性,使您的构建更安全。
- 支持使用 Java 16 进行开发,并为其他有用的功能提供了新功能。
- 通过预编译的 Groovy 脚本插件和包含的构建,更易于编写您的构建。
- 通过新的依赖管理功能,降低多项目构建的维护负担。
- 使用最新版本的 Groovy 和 Kotlin 进行构建脚本编写。
立即升级以在您的构建中尝试这些功能,或使用 Gradle 开始一个新项目。
如果您有兴趣及时了解 Gradle 的新功能和其他发展,请订阅我们的博客并在 Twitter 上关注我们。
我们还发布了过去网络研讨会的视频,内容涉及顶级的 Android 构建问题、依赖管理技术和发布策略。
Gradle 快速入门
使用 gradle init
引导新项目
内置的 init
任务 可用于快速创建新的 Gradle 构建或将 Maven 构建转换为 Gradle 构建。
Gradle 生成的项目采用了最新的推荐构建编写实践。生成的构建演示了如何使用 buildSrc
来共享通用的构建逻辑,并且您可以为 JVM 语言生成多项目构建。
对于从 Maven 迁移到 Gradle 的项目,Gradle 支持生成 Groovy DSL 和 Kotlin DSL 脚本。
可下载的 Gradle 示例
Gradle 提供了一个 示例索引,演示了可以使用 Gradle 构建的不同类型的项目。
这些示例还展示了可以使用 Groovy 或 Kotlin DSL 解决的常见问题,例如向 Java 项目添加集成测试。
性能改进
通过文件系统监视更快地进行最新检查
本地增量构建的快速反馈对于开发者生产力至关重要。当您的 IDE 使用 Gradle 为您的项目构建和运行测试时,尤其如此。文件系统监视通过减少确定自上次构建以来发生的变化所需的磁盘 I/O 量,加快了本地增量构建的速度。
从 Gradle 7.0 开始,此优化在所有受支持的操作系统(包括最新版本的 Windows、Linux 和 MacOS)上默认启用。
有关更多详细信息,请参阅文档。
更快的 Kotlin DSL 脚本编译
Gradle 使用更少的内存压力更快地编译 Kotlin DSL 构建脚本 (*.gradle.kts
)。
当更改共享的构建逻辑(例如 buildSrc 目录中的代码)时,Gradle 还可以完全跳过未受影响的构建脚本文件的编译。
大多数构建可以预期在使用 Gradle 7.0 编辑 Kotlin DSL 构建逻辑时,反馈循环明显缩短。
通过在使用构建缓存时跳过更多工作来加快构建速度
Gradle 包含多项更改,旨在通过选择性地忽略各种不影响系统行为的更改(例如空目录、注释或属性文件中的空格等)来提高 构建缓存 的命中率。
使用实验性配置缓存更快地构建
在运行任何任务之前,Gradle 需要运行配置阶段。目前,这在每次构建调用时都会执行,并且可能会导致明显的延迟,尤其是在大型项目中。
配置缓存通过缓存配置阶段的结果来提高构建性能。使用配置缓存,当没有影响构建配置的更改时,Gradle 可以完全跳过配置阶段,从而使后续构建速度更快。
此外,使用配置缓存时,更多的工作可以并行执行,从而也加速了构建的执行阶段。
请注意,此功能目前是实验性的,默认情况下未启用,并且 Gradle 7.0 的所有核心插件都不支持。
在配置缓存文档中了解有关此新功能及其影响的更多信息。
通过增量分析更快地执行 PMD
PMD 插件 默认使用增量分析。这可以显着减少后续构建的分析时间。
对于依赖于低于 6.0.0 版本的 PMD 的构建,您需要显式禁用增量分析。
更快的临时构建
临时构建机器在重新下载构建使用的所有依赖项时会付出高昂的代价。Gradle 7.0 具有以下功能,可通过跨机器重用依赖项缓存来限制对这些类型构建的影响。
重定位依赖项缓存
可以将 $GRADLE_HOME/caches/modules-2
下的 Gradle 依赖项缓存重定位到另一个目录或主机以缓存依赖项。当移动到新位置或播种到主机映像中时,使用依赖项缓存的构建将不需要访问网络来下载工件或元数据(如果依赖项已下载)。
请注意,创建缓存和使用缓存应使用兼容的 Gradle 版本完成。
有关更多详细信息,请参阅文档。
共享只读依赖项缓存
Gradle 提供了在多个 Gradle 实例之间共享依赖项缓存的功能。
这使得可以拥有一个包含所有构建所需依赖项的单个共享目录。
- 每个容器都可以访问共享的只读依赖项缓存,这避免了构建之间冗余的下载。
- 此缓存可以在容器之间安全共享,而无需创建单独的副本。
请参阅用户手册,了解如何设置共享依赖项缓存。
可用性和新功能
JVM 项目的工具链支持
默认情况下,Gradle 使用相同的 Java 版本来运行 Gradle 本身和构建 JVM 项目,但这并非总是理想的。
在不同的开发者机器和 CI 服务器上使用不同的 Java 版本构建项目可能会导致意外问题。此外,您可能希望使用与运行 Gradle 不兼容的 Java 版本来构建项目。
Gradle 提供了一种设置工具链的方法,通过 java
扩展来构建和测试您的项目
java {
toolchain {
languageVersion = JavaLanguageVersion.of(14)
}
}
Gradle 将检测本地 Java 安装以及来自流行的软件包管理器(如 asdf-vm、jabba 和 SDKMAN!)的其他常见安装位置。如果本地没有可用的 Java 版本与构建的要求匹配,Gradle 将从 AdoptOpenJDK 的网站下载匹配的 JDK。
请参阅用户手册中的工具链文档。
构建、测试和运行 Java 模块
Gradle 支持 Java 模块系统,其中包含编译和执行 Java 模块测试所需的一切。
请参阅包含的示例。
处理用户提供的凭据的约定
构建有时需要用户提供凭据。例如,可能需要凭据才能通过身份验证连接到工件仓库以发布工件。将凭据放在构建脚本之外是一种好的做法。
Gradle 具有一个 API,通过建立使用 Gradle 属性提供凭据的约定,使凭据的使用更加容易,这些属性可以作为命令行参数、环境变量或 gradle.properties
文件中的值提供给构建。当 Gradle 知道构建在某个时候将需要凭据但凭据丢失时,它还引入了快速失败行为。
有关使用新 API 通过身份验证连接到工件仓库的更多详细信息,请参阅用户手册部分以及更新的示例。
可以从命令行为包含的构建执行任务
Gradle 允许用户直接从命令行执行包含的构建中的任务。例如,如果您的构建包含 my-other-project
作为包含的构建,并且它有一个子项目 sub
,其中包含任务 foo
,那么您可以使用以下命令执行 foo
gradle :my-other-project:sub:foo
请注意,与多项目构建不同,运行 gradle build
将不会在所有包含的构建中运行 build
任务。如果您想为包含的构建重新创建此行为,则可以引入任务依赖项到包含的构建中的生命周期任务。
单个依赖项锁定文件格式
依赖项锁定是一种在使用动态依赖项版本时确保可重现构建的机制。
Gradle 7.0 使用单个锁定文件将动态依赖项锁定到其解析的版本。
以前版本的 Gradle 每个配置使用一个文件。Gradle 将自动迁移到单个锁定文件。
安全改进
依赖项验证
典型的项目使用大量的外部依赖项,这使它们面临使用不受信任代码的风险。例如,有人可能会通过传递依赖项意外引入恶意代码。同样,您的构建脚本本身可能容易受到通过受损插件执行的恶意代码的影响。
为了减轻这些风险,Gradle 提供了依赖项验证。依赖项验证使您可以验证构建期间使用的依赖项和插件的校验和和签名。
通过启用依赖项验证,Gradle 将
- 确保依赖项没有被篡改(通过验证其校验和)
- 确保您使用的依赖项和插件的来源(通过验证其签名)
因此降低了将恶意代码运送到生产环境的风险。
有关如何设置依赖项验证的完整说明,请参阅用户手册。
声明独占仓库内容
Gradle 允许您声明应在哪些仓库中搜索特定依赖项。
Gradle 还允许您声明独占内容,这些内容只能在一个仓库中找到,并且不应在任何其他仓库中搜索。
有关详细信息,请参阅用户手册。
验证 Gradle Wrapper 的完整性
Gradle Wrapper 是一个可执行代码的二进制 blob,已签入数百万个 GitHub 仓库。接受对 gradle-wrapper.jar
的更改时,存在安全隐患,这可能并不明显。
我们创建了一个官方 GitHub Action,允许 GitHub 上的项目自动验证其仓库中的 gradle-wrapper.jar
是否由 Gradle 发布。
您仍然可以按照用户手册中的说明手动验证 gradle-wrapper.jar
。
依赖管理
一致的依赖项解析
配置之间的依赖项解析是隔离发生的。这可能会导致一个问题,即测试的运行时类路径可能使用与生产代码的运行时类路径不同的版本。
为了缓解此问题,Gradle 允许您声明依赖项配置之间的一致性,以便一个类路径和另一个类路径之间公共依赖项的版本对齐。
仓库的中心声明
在 settings.gradle (.kts)
中方便地为整个构建定义仓库
dependencyResolutionManagement {
repositories {
mavenCentral ()
}
}
这使 Gradle 可以确保您在构建的所有项目中都使用相同的仓库来解析依赖项。通过阅读有关如何为整个构建声明仓库来了解更多信息。
组件元数据规则的中心声明
在 settings.gradle (.kts)
的中心位置声明 组件元数据规则
dependencyResolutionManagement {
components {
withModule ('com.google.guava: guava', GuavaRule)
}
}
您可以在用户手册中了解有关全局声明规则的更多信息。
用于中心声明依赖项版本的实验性版本目录
在多项目构建中,有多种方法可以共享项目之间的依赖项版本。例如,用户可以直接在构建脚本(在 ext
块中)、外部文件(例如 dependencies.gradle
)、buildSrc
甚至专用插件中声明版本或依赖项坐标。但是,没有任何标准机制可以做到这一点,该机制可以结合每种方法的优点。
Gradle 引入了实验性版本目录,使构建作者可以将第三方依赖项的依赖项坐标(组、工件、版本)集中在常规配置文件中,并以类型安全的方式声明实际依赖项。
实验性类型安全项目访问器
Gradle 具有 类型安全项目访问器 的实验性功能,该功能支持在 IDE 中进行代码完成,以声明对其他项目的依赖项。
构建编写
使用包含的构建进行本地插件开发
到目前为止,作为复合构建的一部分开发插件,以在 约定插件 中组织构建逻辑,仅适用于项目插件(在 build.gradle(.kts)
文件中应用的插件)。设置插件(在 settings.gradle(.kts)
文件中应用的插件)始终必须隔离开发并发布到二进制仓库。
Gradle 在设置文件中提供了一个 DSL 构造,用于包含插件构建。
像这样包含的构建可以同时提供项目插件和设置插件。
pluginManagement {
includeBuild("../my-settings-plugin")
}
plugins {
id("my.settings-plugin")
}
上面的示例假设包含的构建定义了一个 ID 为 my.settings-plugin
的设置插件。
预编译的 Groovy DSL 脚本插件
脚本插件 是拆分和组织长构建脚本的一种便捷方法,但它们有一些局限性和怪癖。
预编译的脚本插件看起来像常规构建脚本,但具有二进制插件的所有优点。它们可以
- 发布到私有仓库或插件门户,
- 使用 TestKit 进行测试,
- 使用
plugins {}
块应用, - 使用
plugins {}
块来应用其他插件。
可以使用 Groovy DSL 和 Kotlin DSL 编写预编译的脚本插件。
预编译的脚本插件 在用户手册中有更深入的介绍。还有一个示例演示了该功能。
包含的构建对 buildSrc 可见
我们建议构建使用特别命名的 buildSrc 构建来组织命令式和通用构建逻辑。
有时,您可能还需要在 buildSrc
本身和您的根构建之间共享构建逻辑。在以前的版本中,这是不可能的,因为 buildSrc
无法访问来自其他包含的构建的构建逻辑。
Gradle 使在 buildSrc 和根构建或任何其他包含的构建之间共享构建逻辑成为可能。这使得在 buildSrc 和其他构建之间共享通用仓库声明或约定变得更容易,如 此示例 中所示。
您可能错过的其他更改
Kotlin 1.4
在 Gradle 7.0 中编写的 Kotlin 构建脚本默认使用 Kotlin 1.4 兼容性级别。
Groovy 3.0
为了支持 JDK 16 并与最新的 Groovy 版本保持同步,Gradle 已升级为在 Groovy DSL 构建脚本中使用 Groovy 3。Groovy 3 配备了新的解析器和许多其他新功能和功能,使与新 Java 功能的互操作性更加容易。
Groovy 2 和 3 之间存在一些不兼容性,升级到 Gradle 7.0 时可能会导致问题。
如果您属于以下情况,则可能会受到 Groovy 升级的影响
- 您正在为您的构建脚本使用 Groovy DSL (
.gradle
文件) - 您正在使用用 Groovy 实现的 Gradle 插件
- 您正在构建用 Groovy 实现的 Gradle 插件
如果您属于以下情况,则不应受到升级的影响
- 您仅使用 Kotlin DSL (
.gradle.kts
文件) - 您仅将 Groovy 用于您的生产代码(您可以选择您需要的 Groovy 版本)
请参阅 Gradle 升级指南,以了解有关升级您的构建和插件以使其与 Groovy 3 兼容的更多信息。
为了解有关 Groovy 3.0 中的改进和新功能的更多信息,请参阅 Groovy 项目的发行说明。
如何升级
我们提供了一份文档,以帮助您从 Gradle 6.x 升级到 Gradle 7.0。如果您使用的是比 Gradle 6.0 更旧的版本,您可能需要先查看Gradle 6.0 中的所有新功能。
在升级之前,我们建议您
- 使用 Gradle Wrapper 升级到 Gradle 6.9。
gradle wrapper --gradle-version=6.9
- 运行
gradle help --scan
以列出所有已弃用的 Gradle API 的使用及其位置。 - 更新您的 Gradle 插件,尤其是 Build Scan™ 的弃用报告中列出的插件。
- 如果您遇到问题,请参阅故障排除指南或在社区论坛上寻求帮助。
您可以通过 @gradle on Twitter 与 Gradle 团队分享反馈。前进并构建快乐!