建议执行任何Gradle构建的方法是在Gradle Wrapper(简称为" Wrapper")的帮助下. Wrapper是一个脚本,它调用已声明版本的Gradle,并在必要时事先下载它. 因此,开发人员可以快速启动并运行Gradle项目,而无需遵循手动安装过程,从而节省了公司的时间和金钱.

wrapper workflow
图1.包装器工作流程

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

  • 在给定的Gradle版本上标准化项目,从而导致更可靠,更可靠的构建.

  • 向不同的用户和执行环境(例如IDE或Continuous Integration服务器)提供新的Gradle版本就像更改包装器定义一样简单.

那么它是怎样工作的? 对于用户而言,通常有三种不同的工作流程:

以下各节将更详细地说明这些用例.

Adding the Gradle Wrapper

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

每个普通的Gradle构建都带有一个称为wrapper的内置任务. 列出任务时,您将可以在"构建安装程序任务"组下找到列出的任务 . 执行wrapper任务会在项目目录中生成必要的包装器文件.

运行包装器任务
$ gradle wrapper
> Task :wrapper

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

要使包装器文件可用于其他开发人员和执行环境,您需要将其检入版本控制. 包括JAR文件在内的所有包装程序文件都非常小. 期望将JAR文件添加到版本控制中. 一些组织不允许项目将二进制文件提交给版本控制. 目前,该方法没有其他选择.

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

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

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

  • 用于执行构建的Gradle版本. 默认情况下, wrapper任务选择用于生成包装器文件的完全相同的Gradle版本.

gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip

所有这些方面都可以在以下命令行选项的帮助下在配置包装文件时进行配置.

--gradle-version

用于下载和执行包装程序的Gradle版本.

--distribution-type

包装器使用的Gradle分布类型. 可用选项为binall . 默认值为bin .

--gradle-distribution-url

指向Gradle分发ZIP文件的完整URL. 使用此选项会使--gradle-version--distribution-type过时,因为URL已包含此信息. 如果要在公司网络中托管Gradle发行版,则此选项非常有用.

--gradle-distribution-sha256-sum

SHA256哈希和用于验证下载的Gradle分布 .

让我们假设以下用例说明了命令行选项的用法. 您想生成版本6.6的Wrapper,并使用-all发行版来使您的IDE启用代码补全功能并能够导航到Gradle源代码. 这些要求由以下命令行执行捕获:

提供包装任务的选项
$ gradle wrapper --gradle-version 6.6 --distribution-type all
> Task :wrapper

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

结果,您可以在包装器属性文件中找到所需的信息.

示例:生成的分发URL
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip

让我们看一下以下项目布局,以说明预期的Wrapper文件:

.
├── build.gradle
├── settings.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

Gradle项目通常提供一个build.gradlesettings.gradle文件. 包装器文件位于gradle目录和项目的根目录中. 以下列表说明了它们的用途.

gradle-wrapper.jar

包装JAR文件,其中包含用于下载Gradle发行版的代码.

gradle-wrapper.properties

一个属性文件,负责配置Wrapper运行时行为,例如与该版本兼容的Gradle版本. 请注意,更多常规设置(例如, 将包装器配置为使用代理 )需要进入其他文件 .

gradlew, gradlew.bat

一个外壳脚本和一个Windows批处理脚本,用于使用包装程序执行构建.

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

Using the Gradle Wrapper

建议始终使用包装程序执行构建,以确保可靠,受控和标准化地执行构建. 使用Wrapper看起来与使用Gradle安装运行构建几乎完全一样. 根据操作系统的不同,您可以运行gradlewgradlew.bat而不是gradle命令. 以下控制台输出演示了Windows机器上包装程序对基于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发行版在计算机上不可用,包装程序将下载它并存储在本地文件系统中. 只要Gradle属性中的分发URL不变,任何后续的构建调用都将重用现有的本地分发.

包装程序外壳程序脚本和批处理文件位于单项目或多项目Gradle构建的根目录中. 如果要从子项目目录(例如../../gradlew tasks执行构建,则需要引用这些文件的正确路径.

Upgrading the Gradle Wrapper

项目通常会希望与时俱进并升级其Gradle版本,以从新功能和改进中受益. 升级Gradle版本的一种方法是手动更改Wrapper的gradle-wrapper.properties文件中的distributionUrl属性. 更好的建议选项是运行wrapper任务并提供目标Gradle版本,如添加Gradle包装器中所述 . 使用wrapper任务可确保对具有该特定Gradle版本的Wrapper Shell脚本或批处理文件进行的所有优化都应用于项目. 与往常一样,您应该将对Wrapper文件的更改提交给版本控制.

请注意,一次运行包装器任务将仅更新gradle-wrapper.properties ,但不影响gradle-wrapper.jar的包装器本身. 这通常很好,因为即使使用古老的包装文件也可以运行Gradle的新版本. 但是,如果您希望所有包装器文件都完全是最新的,则需要再次运行wrapper任务.

使用Gradle wrapper任务来生成包装器,指定版本. 默认为当前版本. 升级包装程序后,可以通过执行./gradlew --version来检查其是否为您期望的./gradlew --version .

示例:升级包装器版本
$ ./gradlew wrapper --gradle-version 6.6

BUILD SUCCESSFUL in 4s
1 actionable task: 1 executed

Customizing the Gradle Wrapper

Gradle的大多数用户对Wrapper的默认运行时行为感到满意. 但是,组织策略,安全性约束或个人喜好可能需要您更深入地定制包装器. 幸运的是,内置的wrapper任务提供了许多选项,可以使运行时行为符合您的需求. 大多数配置选项由基础任务类型Wrapper公开.

假设您每次升级包装程序时-all厌倦了在命令行上定义-all分发类型. 您可以通过重新配置wrapper任务来节省一些键盘笔触.

示例1.定制包装器任务
build.gradle
tasks.named('wrapper') {
    distributionType = Wrapper.DistributionType.ALL
}
build.gradle.kts
tasks.named<Wrapper>("wrapper") {
    distributionType = Wrapper.DistributionType.ALL
}

通过运行./gradlew wrapper --gradle-version 6.6适当配置,足以在Wrapper属性文件中生成一个distributionUrl值,该值将请求-all分发.

生成的分发URL
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip

请查阅API文档,以获取有关可用配置选项的更多详细说明. 您还可以在Gradle发行版中找到用于配置包装器的各种示例.

Authenticated Gradle distribution download

Gradle Wrapper可以使用HTTP基本身份验证从服务器下载Gradle分发. 这使您可以将Gradle分发托管在受保护的私有服务器上. 您可以根据使用情况以两种不同的方式指定用户名和密码:作为系统属性或直接嵌入distributionUrl . 系统属性中的凭据优先于distributionUrl嵌入的凭据.

安全警告

HTTP基本身份验证仅应与HTTPS URL一起使用,而不应与纯HTTP URL一起使用. 使用基本身份验证,用户凭据以明文形式发送.

Using system properties can be done in the .gradle/gradle.properties file in the user’s home directory, or by other means, see Gradle Configuration 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以使用代理的更多信息,请参见通过代理访问网络 .

Verification of downloaded Gradle distributions

Gradle包装器可通过SHA-256哈希总和比较来验证下载的Gradle分发. 通过防止中间人攻击者篡改下载的Gradle发行版,提高了针对目标攻击的安全性.

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

Downloading the SHA-256 file

您可以从稳定发行版候选 发行 版和每晚发行版中下载.sha256文件. 文件的格式是一行文本,它是相应zip文件的SHA-256哈希.

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

Configuring checksum verification

使用distributionSha256Sum属性或在命令行上使用--gradle-distribution-sha256-sum将下载的哈希值添加到gradle-wrapper.properties .

配置SHA-256校验和验证
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10

如果配置的校验和与在托管发行版的服务器上找到的校验和不匹配,则Gradle将报告构建失败. 仅在尚未下载已配置的包装分发程序时才执行校验和验证.

Verifying the integrity of the Gradle Wrapper JAR

包装JAR是一个二进制文件,将在开发人员和构建服务器的计算机上执行. 与所有此类文件一样,在执行文件之前,应确保它是可信任的. 由于通常将Wrapper JAR检查到项目的版本控制系统中,因此恶意参与者有可能通过提交似乎仅升级Gradle版本的拉取请求来用修改后的Java替换原始JAR.

为了验证Wrapper JAR的完整性,Gradle创建了一个GitHub Action ,该GitHub Action根据已知的良好校验和列表自动检查请求请求中的Wrapper JAR. Gradle还会发布所有发行版校验和 (3.3至4.0.2版除外,该版本不会生成可复制的JAR),因此您可以手动验证Wrapper JAR的完整性.

Automatically verifying the Gradle Wrapper JAR on GitHub

GitHub Action与Gradle分开发布,因此请查看其文档以了解如何将其应用于您的项目.

Manually verifying the Gradle Wrapper JAR

您可以通过在主要操作系统之一上运行以下命令来手动验证Wrapper JAR的校验和,以确保未被篡改:

在Linux上手动验证Wrapper JAR的校验和
$ cd gradle/wrapper
$ curl --location --output gradle-wrapper.jar.sha256 \
       https://services.gradle.org/distributions/gradle-6.6-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-6.6-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-6.6-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

Troubleshooting a checksum mismatch

If the checksum does not match the one you expected, chances are the wrapper task wasn’t executed with the upgraded Gradle distribution. Thus, you should first check whether the actual checksum matches the one of a different Gradle version. Here are the commands you can run on the major operating systems to generate the actual checksum of the Wrapper JAR:

在Linux上生成包装器JAR的实际校验和
$ sha256sum gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95  gradle/wrapper/gradle-wrapper.jar
在macOS上生成包装器JAR的实际校验和
$ shasum --algorithm=256 gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95  gradle/wrapper/gradle-wrapper.jar
在Windows上生成包装器JAR的实际校验和(使用PowerShell)
> (Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95

一旦知道了实际的校验和,请检查它是否在https://gradle.org/release-checksums/上列出. 如果已列出,则您已验证包装JAR的完整性. 如果生成Wrapper JAR的Gradle版本与gradle/wrapper/gradle-wrapper.properties中的版本不匹配,则可以安全地再次运行wrapper任务来更新Wrapper JAR.

如果页面上未列出校验和,则包装JAR可能来自里程碑,候选发布版本或每晚构建,或者可能是Gradle 3.3至4.0.2生成的. 您应该尝试找出它是如何生成的,但是除非有其他证明,否则应将其视为不可信的. 如果您认为Wrapper JAR遭到入侵,请通过发送电子邮件至security@gradle.com来通知Gradle团队.