Gradle Wrapper 参考
推荐执行任何 Gradle 构建的方式是借助 Gradle Wrapper(称为“Wrapper”)。
Wrapper 是一个脚本,它调用声明的 Gradle 版本,并在必要时事先下载它。因此,开发人员可以快速启动并运行 Gradle 项目。
简而言之,您将获得以下好处
-
将项目标准化为给定的 Gradle 版本,以实现更可靠和健壮的构建。
-
为不同的用户配置 Gradle 版本只需简单地更改 Wrapper 定义。
-
为不同的执行环境(例如 IDE 或持续集成服务器)配置 Gradle 版本只需简单地更改 Wrapper 定义。
有三种使用 Wrapper 的方法
-
您设置一个新的 Gradle 项目,并添加 Wrapper到其中。
-
您使用 Wrapper 运行一个项目,该项目已经提供了 Wrapper。
-
您将 Wrapper 升级到新的 Gradle 版本。
以下部分将更详细地解释这些用例。
添加 Gradle Wrapper
生成 Wrapper 文件需要您机器上安装的 Gradle 运行时版本,如安装中所述。值得庆幸的是,生成初始 Wrapper 文件是一个一次性过程。
每个原生 Gradle 构建都带有一个内置的任务,名为 wrapper
。当列出任务时,该任务在“构建设置任务”组下列出。
执行wrapper
任务会在项目目录中生成必要的 Wrapper 文件。
$ gradle wrapper
> Task :wrapper BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
为了让其他开发者和执行环境可以使用 Wrapper 文件,您需要将它们检入版本控制系统。Wrapper 文件(包括 JAR 文件)都很小。将 JAR 文件添加到版本控制系统是预期的。一些组织不允许项目将二进制文件提交到版本控制系统,并且没有可用的解决方法。 |
生成的 Wrapper 属性文件,gradle/wrapper/gradle-wrapper.properties
,存储了关于 Gradle 发行版的信息。
-
托管 Gradle 发行版的服务器。
-
Gradle 发行版的类型。默认情况下,
-bin
发行版只包含运行时,不包含示例代码和文档。 -
用于执行构建的 Gradle 版本。默认情况下,
wrapper
任务会选择与生成 Wrapper 文件相同的 Gradle 版本。 -
可选地,下载 Gradle 发行版时使用的超时时间(以毫秒为单位)。
-
可选地,一个布尔值,用于设置发行版 URL 的验证。
以下是 gradle/wrapper/gradle-wrapper.properties
中生成的发行版 URL 的示例。
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
所有这些方面都可以在使用以下命令行选项生成 Wrapper 文件时进行配置。
--gradle-version
-
用于下载和执行 Wrapper 的 Gradle 版本。在将发行版 URL 写入属性文件之前,会对其进行验证。
允许使用以下标签:
--distribution-type
-
用于 Wrapper 的 Gradle 发行版类型。可用的选项是
bin
和all
。默认值为bin
。 --gradle-distribution-url
-
指向 Gradle 发行版 ZIP 文件的完整 URL。此选项使
--gradle-version
和--distribution-type
变得多余,因为 URL 已经包含了这些信息。如果您想在公司网络内部托管 Gradle 发行版,此选项非常有用。在将 URL 写入属性文件之前,会对其进行验证。 --gradle-distribution-sha256-sum
-
用于验证下载的 Gradle 发行版的 SHA256 哈希值。
--network-timeout
-
下载 Gradle 发行版时使用的网络超时时间(以毫秒为单位)。默认值为
10000
。 --no-validate-url
-
禁用对配置的发行版 URL 的验证。
--validate-url
-
启用对配置的发布 URL 的验证。默认情况下启用。
如果发布 URL 使用 `--gradle-version` 或 `--gradle-distribution-url` 配置,则通过在 `https` 方案的情况下发送 HEAD 请求或在 `file` 方案的情况下检查文件是否存在来验证 URL。
假设以下用例来说明命令行选项的使用。您希望使用版本 8.7 生成 Wrapper,并使用 `-all` 发布来启用您的 IDE 以启用代码完成并能够导航到 Gradle 源代码。
以下命令行执行捕获了这些要求
$ gradle wrapper --gradle-version 8.7 --distribution-type all > Task :wrapper BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
结果,您可以在 Wrapper 属性文件中找到所需的信息(生成的发布 URL)
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
让我们看一下以下项目布局来说明预期的 Wrapper 文件
.
├── a-subproject
│ └── build.gradle.kts
├── settings.gradle.kts
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
.
├── a-subproject
│ └── build.gradle
├── settings.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
Gradle 项目通常提供一个 `settings.gradle(.kts)` 文件和每个子项目一个 `build.gradle(.kts)` 文件。Wrapper 文件与项目根目录中的 `gradle` 目录并存。
以下列表解释了它们的用途
gradle-wrapper.jar
-
包含用于下载 Gradle 发布的代码的 Wrapper JAR 文件。
gradle-wrapper.properties
-
一个属性文件,负责配置 Wrapper 运行时行为,例如与该版本兼容的 Gradle 版本。请注意,更通用的设置,例如 配置 Wrapper 使用代理,需要进入 不同的文件。
gradlew
,gradlew.bat
-
一个 shell 脚本和一个 Windows 批处理脚本,用于使用 Wrapper 执行构建。
您可以继续 使用 Wrapper 执行构建,而无需安装 Gradle 运行时。如果您正在处理的项目不包含这些 Wrapper 文件,则需要 生成它们。
使用 Gradle Wrapper
始终建议使用 Wrapper 执行构建,以确保构建的可靠、受控和标准化执行。使用 Wrapper 就像使用 Gradle 安装运行构建一样。根据您的操作系统,您运行 `gradlew` 或 `gradlew.bat` 而不是 `gradle` 命令。
以下控制台输出演示了在 Windows 计算机上使用 Wrapper 的 Java 项目
$ gradlew.bat build Downloading https://services.gradle.org/distributions/gradle-5.0-all.zip ..................................................................................... Unzipping C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0-all.zip to C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-al\ac27o8rbd0ic8ih41or9l32mv Set executable permissions for: C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0\bin\gradle BUILD SUCCESSFUL in 12s 1 actionable task: 1 executed
如果 Gradle 发布在机器上不可用,Wrapper 将下载它并将其存储在本地文件系统中。只要 Gradle 属性中的发布 URL 不变,任何后续的构建调用都会重用现有的本地发布。
Wrapper shell 脚本和批处理文件位于单个或多项目 Gradle 构建的根目录中。如果您想从子项目目录执行构建,例如 `../../gradlew tasks`,则需要引用这些文件的正确路径。 |
升级 Gradle Wrapper
项目通常希望与时俱进,升级其 Gradle 版本以利用新功能和改进。
升级 Gradle 版本的一种方法是手动更改 Wrapper 的 gradle-wrapper.properties
文件中的 distributionUrl
属性。
更好的推荐方法是运行 wrapper
任务并提供目标 Gradle 版本,如 添加 Gradle Wrapper 中所述。使用 wrapper
任务可确保对 Wrapper shell 脚本或批处理文件进行的任何针对特定 Gradle 版本的优化都将应用于项目。
像往常一样,您应该将对 Wrapper 文件的更改提交到版本控制中。
请注意,运行一次 wrapper 任务只会更新 gradle-wrapper.properties
,而不会触及 gradle-wrapper.jar
中的 wrapper 本身。这通常没问题,因为即使使用旧的 wrapper 文件,也可以运行新版本的 Gradle。
如果您希望所有 wrapper 文件完全更新,则需要再次运行 wrapper 任务。
|
以下命令将 Wrapper 升级到最新
版本
$ ./gradlew wrapper --gradle-version latest BUILD SUCCESSFUL in 4s 1 actionable task: 1 executed
以下命令将 Wrapper 升级到特定版本
$ ./gradlew wrapper --gradle-version 8.7 BUILD SUCCESSFUL in 4s 1 actionable task: 1 executed
升级 Wrapper 后,您可以通过执行 ./gradlew --version
来检查它是否为预期版本。
不要忘记再次运行 wrapper
任务以下载 Gradle 分发二进制文件(如果需要)并更新 gradlew
和 gradlew.bat
文件。
自定义 Gradle Wrapper
大多数 Gradle 用户对 Wrapper 的默认运行时行为感到满意。但是,组织策略、安全约束或个人偏好可能要求您深入了解 Wrapper 的自定义。
值得庆幸的是,内置的 wrapper
任务公开了许多选项,可以根据您的需要调整运行时行为。大多数配置选项由底层任务类型 Wrapper 公开。
假设您厌倦了每次升级 Wrapper 时都在命令行上定义 -all
分发类型。您可以通过重新配置 wrapper
任务来节省一些键盘操作。
tasks.wrapper {
distributionType = Wrapper.DistributionType.ALL
}
tasks.named('wrapper') {
distributionType = Wrapper.DistributionType.ALL
}
配置完成后,运行 ./gradlew wrapper --gradle-version 8.7
即可在 Wrapper 属性文件中生成 distributionUrl
值,该值将请求 -all
分发版。
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
查看 API 文档 以获取有关可用配置选项的更详细说明。您还可以在 Gradle 分发版中找到 配置 Wrapper 的各种示例。
经过身份验证的 Gradle 分发版下载
Gradle Wrapper
可以使用 HTTP 基本身份验证从服务器下载 Gradle 分发版。这使您能够将 Gradle 分发版托管在受保护的私有服务器上。
您可以根据您的用例以两种不同的方式指定用户名和密码:作为系统属性或直接嵌入到 distributionUrl
中。系统属性中的凭据优先于嵌入到 distributionUrl
中的凭据。
HTTP 基本身份验证仅应与 |
系统属性可以在用户主目录中的 .gradle/gradle.properties
文件中指定,也可以通过其他 方式 指定。
要指定 HTTP 基本身份验证凭据,请将以下行添加到系统属性文件
systemProp.gradle.wrapperUser=username
systemProp.gradle.wrapperPassword=password
在 gradle/wrapper/gradle-wrapper.properties
文件中的 distributionUrl
中嵌入凭据也有效。请注意,此文件将被提交到您的源代码控制系统中。
嵌入到 distributionUrl 中的共享凭据仅应在受控环境中使用。
|
要在 distributionUrl
中指定 HTTP 基本身份验证凭据,请添加以下行
distributionUrl=https://username:password@somehost/path/to/gradle-distribution.zip
这可以与代理一起使用,无论代理是否经过身份验证。有关如何配置 Wrapper
以使用代理的更多信息,请参阅 通过代理访问网络。
下载的 Gradle 分发版的验证
Gradle Wrapper 允许通过 SHA-256 哈希和比较来验证下载的 Gradle 分发版。这通过防止中间人攻击者篡改下载的 Gradle 分发版来提高安全性。
要启用此功能,请下载与您要验证的 Gradle 分发版关联的 .sha256
文件。
下载 SHA-256 文件
您还可以参考 Gradle 分发版校验和列表。
配置校验和验证
将下载的(SHA-256 校验和)哈希值添加到 gradle-wrapper.properties
中,使用 distributionSha256Sum
属性,或者在命令行中使用 --gradle-distribution-sha256-sum
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10
如果配置的校验和与托管分发的服务器上找到的校验和不匹配,Gradle 将报告构建失败。只有在配置的 Wrapper 分发尚未下载的情况下才会执行校验和验证。
如果 gradle-wrapper.properties 包含 distributionSha256Sum ,但任务配置未定义校验和,则 Wrapper 任务将失败。当 Gradle 版本没有改变时,执行 Wrapper 任务会保留 distributionSha256Sum 配置。
|
验证 Gradle Wrapper JAR 的完整性
Wrapper JAR 是一个二进制文件,将在开发人员和构建服务器的计算机上执行。与所有此类文件一样,您应该在执行它之前确保它是可信的。
由于 Wrapper JAR 通常被检入项目的版本控制系统,因此恶意攻击者有可能通过提交仅升级 Gradle 版本的拉取请求来替换原始 JAR。
为了验证 Wrapper JAR 的完整性,Gradle 创建了一个 GitHub Action,它会自动检查拉取请求中的 Wrapper JAR 与已知良好校验和列表的匹配情况。
Gradle 还发布了 所有版本的校验和(除了版本 3.3 到 4.0.2,它们没有生成可重复的 JAR),因此您可以手动验证 Wrapper JAR 的完整性。
在 GitHub 上自动验证 Gradle Wrapper JAR
GitHub Action 是与 Gradle 分开发布的,因此请查看其文档以了解如何将其应用于您的项目。
手动验证 Gradle Wrapper JAR
您可以手动验证 Wrapper JAR 的校验和,以确保它没有被篡改,方法是在主要操作系统之一上运行以下命令。
手动验证 Wrapper JAR 在 Linux 上的校验和
$ cd gradle/wrapper
$ curl --location --output gradle-wrapper.jar.sha256 \ https://services.gradle.org/distributions/gradle-{gradleVersion}-wrapper.jar.sha256
$ echo " gradle-wrapper.jar" >> gradle-wrapper.jar.sha256
$ sha256sum --check gradle-wrapper.jar.sha256
gradle-wrapper.jar: OK
手动验证 Wrapper JAR 在 macOS 上的校验和
$ cd gradle/wrapper
$ curl --location --output gradle-wrapper.jar.sha256 \ https://services.gradle.org/distributions/gradle-{gradleVersion}-wrapper.jar.sha256
$ echo " gradle-wrapper.jar" >> gradle-wrapper.jar.sha256
$ shasum --check gradle-wrapper.jar.sha256
gradle-wrapper.jar: OK
手动验证 Windows 上 Wrapper JAR 的校验和(使用 PowerShell)
> $expected = Invoke-RestMethod -Uri https://services.gradle.org/distributions/gradle-8.7-wrapper.jar.sha256
> $actual = (Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
> @{$true = 'OK: Checksum match'; $false = "ERROR: Checksum mismatch!`nExpected: $expected`nActual: $actual"}[$actual -eq $expected]
OK: Checksum match
解决校验和不匹配问题
如果校验和与预期不符,则很可能是 wrapper
任务未使用升级后的 Gradle 发行版执行。
您应该首先检查实际校验和是否与其他 Gradle 版本匹配。
以下是在主要操作系统上生成 Wrapper JAR 实际校验和的命令。
生成 Linux 上 Wrapper JAR 的校验和
$ sha256sum gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
生成 macOS 上 Wrapper JAR 的实际校验和
$ shasum --algorithm=256 gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
生成 Windows 上 Wrapper JAR 的实际校验和(使用 PowerShell)
> (Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95
一旦您知道实际校验和,请检查它是否列在 https://gradle.org.cn/release-checksums/ 上。如果它被列出,您已验证 Wrapper JAR 的完整性。如果生成 Wrapper JAR 的 Gradle 版本与 gradle/wrapper/gradle-wrapper.properties
中的版本不匹配,则可以安全地再次运行 wrapper
任务以更新 Wrapper JAR。
如果校验和未在页面上列出,则 Wrapper JAR 可能来自里程碑、候选发布版或每日构建,或者可能由 Gradle 3.3 到 4.0.2 生成。尝试找出它是如何生成的,但在得到证实之前将其视为不可信。如果您认为 Wrapper JAR 已被破坏,请通过发送电子邮件至 [email protected] 告知 Gradle 团队。