建议执行任何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.0.1-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

The SHA256 hash sum used for verifying the downloaded Gradle distribution.

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

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

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

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

示例:生成的分发URL
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-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属性文件中的distributionUrl属性. 更好的建议选项是运行wrapper任务并提供目标Gradle版本,如添加Gradle包装器中所述 . 使用wrapper任务可确保对具有该特定Gradle版本的Wrapper Shell脚本或批处理文件所做的任何优化都应用于项目. 像往常一样,您需要将对Wrapper文件的更改提交给版本控制.

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

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

BUILD SUCCESSFUL in 4s
1 actionable task: 1 executed

Customizing the Gradle Wrapper

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

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

示例1.定制包装器任务
build.gradle
wrapper {
    distributionType = Wrapper.DistributionType.ALL
}
build.gradle.kts
tasks.wrapper {
    distributionType = Wrapper.DistributionType.ALL
}

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

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

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

Authenticated Gradle distribution download

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

💡
安全警告

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

可以在用户主目录的.gradle/gradle.properties文件中使用系统属性,也可以通过其他方式(请参阅Gradle配置属性)进行操作 .

Specifying the HTTP Basic Authentication credentials using system properties
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 checksum of the Gradle Wrapper JAR

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

为了检查Wrapper JAR的完整性,Gradle在https://services.gradle上与所有 Gradle发行版一起发布了所有发行版校验和 (3.3至4.0.2版除外,该版本未生成可再现的JAR) . org / . 您可以通过在主要操作系统之一上运行以下命令来手动验证Wrapper JAR的校验和,以确保未被篡改:

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

如果校验和与您期望的校验和不匹配,则可能是升级的Gradle发行版未执行wrapper任务. 因此,您应该首先检查实际校验和是否与其他Gradle版本之一匹配. 您可以在主要操作系统上运行以下命令来生成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的完整性. 但是,它属于不同的-可能是较旧的-Gradle版本. 在这种情况下,再次运行wrapper任务以更新Wrapper JAR是安全的,因此它与gradle/wrapper/gradle-wrapper.properties中的Gradle版本匹配.

如果页面上未列出校验和,则包装JAR可能来自里程碑,候选发布版本或每晚生成的版本,或者可能确实不合法. 您应该尝试找出它是如何生成的,但是除非有其他证明,否则应将其视为不可信的. 如果您认为它是被人为操纵的,请发送电子邮件至security@gradle.com告知Gradle团队.