执行任何 Gradle 构建的推荐方法是借助 Gradle Wrapper(称为“Wrapper”)。

Wrapper 是一个调用 Gradle 声明版本的脚本,如有必要,请提前下载它。因此,开发人员可以快速启动并运行 Gradle 项目。

包装工作流程

简而言之,您可以获得以下好处:

  • 在给定 Gradle 版本上标准化项目,以获得更可靠、更健壮的构建。

  • 通过简单的 Wrapper 定义更改即可为不同用户配置 Gradle 版本。

  • 通过简单的 Wrapper 定义更改即可为不同的执行环境(例如 IDE 或持续集成服务器)配置 Gradle 版本。

Wrapper 的使用方法有以下三种:

  1. 您设置一个新的 Gradle 项目并向其中添加 Wrapper 。

  2. 您可以使用已提供的包装器来运行项目。

  3. 将 Wrapper 升级到新版本的 Gradle。

以下部分更详细地解释了每个用例。

添加 Gradle 包装器

生成 Wrapper 文件需要在计算机上安装 Gradle 运行时版本,如安装中所述。值得庆幸的是,生成初始包装文件是一次性过程。

每个普通 Gradle 构建都带有一个名为 的内置任务wrapper列出任务时,该任务列在“构建设置任务”组下。

执行wrapper任务会在项目目录中生成必要的Wrapper文件:

$ gradle wrapper
> Task :wrapper

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

为了使 Wrapper 文件可供其他开发人员和执行环境使用,您需要将它们签入版本控制。包装文件(包括 JAR 文件)都很小。预计将 JAR 文件添加到版本控制中。某些组织不允许项目将二进制文件提交到版本控制,并且没有可用的解决方法。

生成的 Wrapper 属性文件gradle/wrapper/gradle-wrapper.properties存储有关 Gradle 发行版的信息:

  • 托管Gradle 发行版的服务器。

  • Gradle 分布的类型。默认情况下,该-bin发行版仅包含运行时,但不包含示例代码和文档。

  • 用于执行构建的Gradle 版本。默认情况下,wrapper任务选择用于生成 Wrapper 文件的相同 Gradle 版本。

  • (可选)下载 Gradle 发行版时使用的超时(以毫秒为单位)。

  • (可选)用于设置分发 URL 验证的布尔值

以下是在 中生成的分发 URL 的示例gradle/wrapper/gradle-wrapper.properties

distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip

所有这些方面都可以在生成包装文件时借助以下命令行选项进行配置:

--gradle-version

用于下载和执行 Wrapper 的 Gradle 版本。生成的分发 URL 在写入属性文件之前会经过验证。

允许使用以下标签:

--distribution-type

用于 Wrapper 的 Gradle 分发类型。可用选项有binall。默认值为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或,则通过在方案的情况下发送 HEAD 请求或在方案的情况下通过检查文件的存在来--gradle-distribution-url验证 URL 。httpsfile

让我们假设以下用例来说明命令行选项的使用。您希望生成版本 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)包装文件位于gradle项目的目录和根目录中。

以下列表解释了它们的用途:

gradle-wrapper.jar

包含用于下载 Gradle 发行版的代码的 Wrapper JAR 文件。

gradle-wrapper.properties

负责配置 Wrapper 运行时行为的属性文件,例如与此版本兼容的 Gradle 版本。请注意,更通用的设置(例如将 Wrapper 配置为使用代理)需要放入不同的文件中。

gradlew,gradlew.bat

用于使用 Wrapper 执行构建的 shell 脚本和 Windows 批处理脚本。

您可以继续使用 Wrapper 执行构建,而无需安装 Gradle 运行时。如果您正在处理的项目不包含这些 Wrapper 文件,您将需要生成它们

使用 Gradle 包装器

始终建议使用 Wrapper 执行构建,以确保构建的可靠、受控和标准化执行。使用 Wrapper 看起来就像使用 Gradle 安装来运行构建。根据您运行gradlewgradlew.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 包装器

项目通常希望与时俱进并升级其 Gradle 版本,以从新功能和改进中受益。

升级 Gradle 版本的一种方法是手动更改distributionUrlWrappergradle-wrapper.properties文件中的属性。

更好且推荐的选项是运行wrapper任务并提供目标 Gradle 版本,如添加 Gradle 包装器中所述。使用该wrapper任务可确保对特定 Gradle 版本的 Wrapper shell 脚本或批处理文件所做的任何优化都应用于项目。

像往常一样,您应该将对 Wrapper 文件的更改提交给版本控制。

请注意,运行包装器任务一次只会更新gradle-wrapper.properties,但包装器本身保持gradle-wrapper.jar不变。这通常没问题,因为新版本的 Gradle 甚至可以使用较旧的包装文件运行。

如果您希望所有包装器文件完全是最新的,则需要wrapper再次运行该任务。

以下命令将 Wrapper 升级到latest版本:

$ ./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

升级包装器后,您可以通过执行来检查它是否是您期望的版本./gradlew --version

不要忘记wrapper再次运行任务来下载 Gradle 分发二进制文件(如果需要)并更新gradlewgradlew.bat文件。

自定义 Gradle 包装器

大多数 Gradle 用户对 Wrapper 的默认运行时行为感到满意。但是,组织策略、安全限制或个人偏好可能要求您更深入地自定义包装器。

值得庆幸的是,内置wrapper任务提供了许多选项,可以根据您的需要调整运行时行为。大多数配置选项由底层任务类型Wrapper公开。

假设您厌倦了-all每次升级 Wrapper 时在命令行上定义分发类型。您可以通过重新配置任务来节省一些键盘敲击次数wrapper

build.gradle.kts
tasks.wrapper {
    distributionType = Wrapper.DistributionType.ALL
}
build.gradle
tasks.named('wrapper') {
    distributionType = Wrapper.DistributionType.ALL
}

配置到位后,运行./gradlew wrapper --gradle-version 8.7足以distributionUrl在 Wrapper 属性文件中生成一个值,该值将请求-all分发:

distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip

查看API 文档,了解可用配置选项的更详细说明。您还可以在 Gradle 发行版中找到用于配置 Wrapper 的各种示例。

经过身份验证的 Gradle 发行版下载

GradleWrapper可以使用 HTTP 基本身份验证从服务器下载 Gradle 发行版。这使您能够在私人受保护的服务器上托管 Gradle 发行版。

您可以根据您的用例以两种不同的方式指定用户名和密码:作为系统属性或直接嵌入到distributionUrl.系统属性中的凭据优先于distributionUrl.

HTTP 基本身份验证只能与HTTPSURL 一起使用,而不能与普通HTTPURL 一起使用。使用基本身份验证时,用户凭据以明文形式发送。

.gradle/gradle.properties系统属性可以在用户主目录中的文件中或通过其他方式指定。

要指定 HTTP 基本身份验证凭据,请将以下行添加到系统属性文件中:

systemProp.gradle.wrapperUser=username
systemProp.gradle.wrapperPassword=password

将凭据嵌入到文件中distributionUrlgradle/wrapper/gradle-wrapper.properties可以。请注意,该文件将被提交到您的源代码控制系统中。

嵌入的共享凭据distributionUrl只能在受控环境中使用。

要在 中指定 HTTP 基本身份验证凭据distributionUrl,请添加以下行:

distributionUrl=https://username:password@somehost/path/to/gradle-distribution.zip

这可以与经过身份验证或未经身份验证的代理结合使用。有关如何配置以使用代理的更多信息,请参阅通过代理访问网络。Wrapper

验证下载的 Gradle 发行版

Gradle Wrapper 允许通过 SHA-256 哈希和比较来验证下载的 Gradle 发行版。这可以防止中间人攻击者篡改下载的 Gradle 发行版,从而提高针对针对性攻击的安全性。

要启用此功能,请下载.sha256与要验证的 Gradle 发行版关联的文件。

下载 SHA-256 文件

您可以.sha256稳定版本候选版本和夜间版本下载该文件。文件的格式是单行文本,它是相应 zip 文件的 SHA-256 哈希值。

您还可以参考Gradle 分发校验和列表

配置校验和验证

将下载的(SHA-256 校验和)哈希和添加到gradle-wrapper.properties使用属性或在命令行上distributionSha256Sum使用:--gradle-distribution-sha256-sum

distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10

如果配置的校验和与托管发行版的服务器上找到的校验和不匹配,Gradle 将报告构建失败。仅当尚未下载配置的 Wrapper 发行版时才会执行校验和验证。

如果包含,则 任务Wrapper失败,但任务配置未定义总和。当 Gradle 版本未更改时, 执行任务会保留配置。gradle-wrapper.propertiesdistributionSha256SumWrapperdistributionSha256Sum

验证 Gradle Wrapper JAR 的完整性

Wrapper JAR 是一个二进制文件,将在开发人员和构建服务器的计算机上执行。与所有此类文件一样,您应该在执行之前确保它是可信的。

由于 Wrapper JAR 通常会签入项目的版本控制系统,因此恶意行为者有可能通过提交仅升级 Gradle 版本的拉取请求,将原始 JAR 替换为修改后的 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 的校验和,以确保其未被篡改。

在 Linux 上手动验证 Wrapper JAR 的校验和:

$ 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

在 macOS 上手动验证 Wrapper JAR 的校验和:

$ 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/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 已被泄露,请发送电子邮件至security@gradle.com告知 Gradle 团队。