本章提供了将 Gradle 6.x 构建迁移到 Gradle 7.0 所需的信息。要从 Gradle 5.x 或更早版本迁移,请先完成较旧的迁移指南

我们建议所有用户执行以下步骤

  1. 尝试运行 gradle help --scan 并查看生成的构建扫描的弃用视图

    Deprecations View of a Gradle Build Scan

    这样,你可以看到适用于你的构建的任何弃用警告。

    或者,你可以运行 gradle help --warning-mode=all 以在控制台中查看弃用,尽管它可能不会报告太多详细信息。

  2. 更新你的插件。

    一些插件将与此新版本的 Gradle 冲突,例如,因为它们使用已删除或更改的内部 API。当插件尝试使用 API 的弃用部分时,上一步将通过发出弃用警告来帮助你识别潜在问题。

  3. 运行 gradle wrapper --gradle-version 7.0 以将项目更新到 7.0。

  4. 尝试运行项目并使用故障排除指南调试任何错误。

从 6.9 及更早版本升级

IDE 集成中的更改

IDEA 模型中的更改

getGeneratedSourceDirectories()getGeneratedTestDirectories() 方法已从 IdeaContentRoot 接口中移除。客户端应使用 getSourceDirectories()getTestDirectories() 替换这些调用,并在返回的实例上使用 isGenerated() 方法。

依赖锁定现在默认为每个项目一个文件

依赖锁定文件的格式已更改,因此每个项目只有一个文件,而不是每个项目每个配置一个文件。此更改仅影响锁定文件的写入。Gradle 仍然能够加载以较旧格式保存的锁定状态。

前往 文档 了解如何迁移到新格式。迁移可以按配置执行,不必一步完成。Gradle 会在将它们迁移到新文件格式时自动清理以前的锁定文件。

Gradle 模块元数据现在默认可重复

buildId 字段将不会默认填充,以确保在没有构建输入更改的情况下,生成的元数据文件保持不变。用户仍然可以选择将此唯一标识符作为生成的元数据的一部分,请参阅 文档

jcenter() 快捷方法现已弃用

JFrog 宣布 JCenter 存储库将于 2021 年 2 月停止使用。许多 Gradle 构建依赖 JCenter 获取项目依赖项。

没有新的软件包或版本发布到 JCenter,但 JFrog 表示他们会无限期地让 JCenter 保持只读状态。我们建议您考虑 使用 mavenCentral()google() 或私有 maven 存储库。

jcenter() 被用作存储库时,Gradle 会发出弃用警告,并且此方法计划在 Gradle 8.0 中移除。

潜在的重大更改

捆绑的 Gradle 依赖项更新

对 Groovy 和 Groovy DSL 的更改

由于更新至 Groovy 的下一个主要版本,在升级至 Gradle 7.0 时,您可能会遇到小问题。

新版本的 Groovy 有一个更严格的解析器,它无法编译在以前 Groovy 版本中可能被接受的代码。如果您遇到语法错误,请查看 Groovy 问题跟踪器Groovy 3 发布亮点

一些非常具体的回归 已在 Groovy 的下一个小版本中修复。

Groovy 模块化

Gradle 不再嵌入将所有 Groovy 模块捆绑到一个 jar 中的 groovy-all 副本——只有最重要的模块在 Gradle 分发中分发。

localGroovy() 依赖项将包括以下 Groovy 模块

  • groovy

  • groovy-ant

  • groovy-astbuilder

  • groovy-console

  • groovy-datetime

  • groovy-dateutil

  • groovy-groovydoc

  • groovy-json

  • groovy-nio

  • groovy-sql

  • groovy-templates

  • groovy-test

  • groovy-xml

但以下 Groovy 模块包括在内

  • groovy-cli-picocli

  • groovy-docgenerator

  • groovy-groovysh

  • groovy-jmx

  • groovy-jsr223

  • groovy-macro

  • groovy-servlet

  • groovy-swing

  • groovy-test-junit5

  • groovy-testng

您可以将这些依赖项拉入您的构建,就像拉入任何其他外部依赖项一样。

使用 Groovy 3 构建 Gradle 插件

使用 gradleApi()localGroovy() 时,使用 Gradle 7.0 构建的插件现在在其类路径上会有 Groovy 3。

如果您使用 Spock 来测试您的插件,您将需要使用 Spock 2.x。Spock 1.x 和 Groovy 3 没有兼容版本。
dependencies {
    // Ensure you use the Groovy 3.x variant
    testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') {
        exclude group: 'org.codehaus.groovy'
    }
}

// Spock 2 is based on JUnit Platform which needs to be enabled explicitly.
tasks.withType(Test).configureEach {
    useJUnitPlatform()
}
性能

根据子项目和 Groovy DSL 构建脚本的数量,您可能会注意到在首次编译构建脚本或对构建脚本的类路径进行更改时性能下降。这是由于 Groovy 3 解析器性能较慢,但 Groovy 团队已意识到此问题并尝试减轻性能下降。

总体而言,我们还在研究如何提高 Groovy DSL 和 Kotlin DSL 的构建脚本编译性能。

遇到“在 DefaultDependencyHandler 上找不到方法 X 的参数 Y”

虽然以下错误最初看起来像编译错误,但实际上是由于已删除特定 `Configuration`。有关更多详细信息,请参阅 删除 compileruntime 配置

Could not find method testCompile() for arguments [DefaultExternalModuleDependency{group='org.junit', name='junit-bom', version='5.7.0', configuration='default'}] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

更新默认工具集成版本

删除 compileruntime 配置

自 Gradle 诞生以来,它提供了 compileruntime 配置来声明依赖项。但是,这些配置不支持依赖项的细粒度范围。因此,在 Gradle 3.4 中引入了更好的替代方案

  • implementation 配置应用于声明依赖项,这些依赖项是库的实现细节:在编译时对库的使用者不可见。

  • api 配置(仅在应用 java-library 插件时可用)应用于声明依赖项,这些依赖项是库的 API 的一部分,需要在编译时向使用者公开。

在 Gradle 7 中,compileruntime 配置均已删除。因此,您必须迁移到上述 implementationapi 配置。如果您仍在为 Java 库使用 java 插件,则需要改用 java-library 插件。

表 1. 常见配置升级
已删除的配置 新配置

compile

apiimplementation

runtime

runtimeOnly

testRuntime

testRuntimeOnly

testCompile

testImplementation

<sourceSet>Runtime

<sourceSet>RuntimeOnly

<sourceSet>Compile

<sourceSet>Implementation

你可以通过阅读Java 库插件文档,找到有关新配置的优势以及在何处使用它们以替代 compileruntime 的更多详细信息。

在使用 Groovy DSL 时,在处理已删除的配置时,你需要注意一个特定的升级问题。

如果你正在创建扩展已删除配置之一的自定义配置,Gradle 可能会在不提示的情况下创建不存在的配置。

这看起来像

configurations {
  // This silently creates a configuration called "runtime"
  myConf extendsFrom runtime
}

自定义配置的相关依赖项解析结果可能与 Gradle 6.x 或更早版本不同。你可能会注意到缺少依赖项或工件。

ProjectBuilder 的临时项目文件位置

ProjectBuilder API 用于在单元测试中检查 Gradle 构建。此 API 用于在系统临时目录(由 java.io.tmpdir 定义)下创建临时项目文件。

现在,此 API 会在 Test 任务的临时目录下创建临时项目文件。此路径通常位于项目构建目录下。当测试期望特定的文件路径时,这可能会导致测试失败。

如果测试使用 ProjectBuilder.withProjectDir(…​),则不受影响。

TestKit 测试的临时文件位置

使用TestKit API 的测试用于在系统临时目录(由 java.io.tmpdir 定义)下创建临时文件。这些文件用于存储 Gradle 发行版的副本或另一个仅限测试的 Gradle 用户主目录。

现在,TestKit 测试会在 Test 任务的临时目录下创建临时文件。此路径通常位于项目构建目录下。当测试期望特定的文件路径时,这可能会导致测试失败。

如果测试使用 GradleRunner.withTestKitDir(…​),则不受影响。

在 Windows 上使用 TestKit 进行文件系统监视

Windows 上的文件系统监视实现向根项目目录添加一个锁,以便监视更改。在使用 TestKit 运行构建后尝试删除根项目目录时,这可能会导致错误。例如,将 TestKit 与 JUnit 的 @TempDir 扩展或 TemporaryFolder 规则结合使用的测试可能会遇到此问题。为了避免这些文件锁的问题,TestKit 禁用了通过 GradleRunner 在 Windows 上执行的构建的文件系统监视。如果你想覆盖默认行为,可以通过将 --watch-fs 传递给 GradleRunner.withArguments() 来启用文件系统监视。

删除旧版 maven 插件

maven 插件已删除。您应该改用 maven-publish 插件。

请参阅 Maven Publish 插件文档 了解更多详情。

删除 uploadArchives 任务

uploadArchives 任务与旧版 Ivy 或 Maven 发布机制结合使用。它已在 Gradle 7 中删除。您应该改用 maven-publishivy-publish 插件。

请参阅 Maven Publish 插件文档 以在 Maven 存储库中发布。请参阅 Ivy Publish 插件文档 以在 Ivy 存储库中发布。

依赖项版本排序中的更改

在依赖项版本排序的上下文中,-SNAPSHOT 版本现在被认为在最终版本之前,但在任何 -RC 版本之后。还考虑了更多特殊版本后缀。这使 Gradle 算法更接近 Maven 算法,适用于众所周知的版本后缀。

查看 文档 以了解 Gradle 应用的所有规则。

删除 Play Framework 插件

已弃用的 Play 插件已删除。从插件门户网站可获得外部替代品,即 Play Framework 插件

删除已弃用的 JVM 插件

已删除这些未维护的备用 JVM 插件:java-langscala-langjunit-test-suitejvm-componentjvm-resources

请改用稳定的 Java LibraryScala 插件。

移除实验性 JavaScript 插件

以下用于实验性 JavaScript 集成的插件现已从发行版中移除:coffeescript-baseenvjsjavascript-basejshintrhino

如果您使用了这些插件(尽管它们是实验性质的),您可以在 插件门户 中找到合适的替代品。

配置 Ivy 存储库的布局

采用配置块的 layout 方法已移除,并被 patternLayout 替换。

现在,在没有设置文件的情况下执行 Gradle 构建将产生错误

Gradle 构建由其在当前或父目录中找到的 settings.gradle(.kts) 文件定义。如果没有设置文件,则 Gradle 构建未定义,并且 Gradle 在尝试执行任务时会产生错误。

对此的例外情况是使用 init 任务调用 Gradle 或使用诊断命令行标志(例如 --version)。

现在,在项目评估后调用 Project.afterEvaluate() 将产生错误

Gradle 6.x 会警告用户错误的行为,并在这种情况下忽略目标操作。从 7.0 开始,相同的情况将产生错误。插件和构建脚本应调整为仅在配置时调用 afterEvaluate。如果您遇到此类构建失败,并且相关的 afterEvaluate 语句在您的构建源中声明,则可以简单地将其删除。如果 afterEvaluate 在插件中声明,则向插件维护者报告该问题。

现在,在值最终确定后修改文件集合将产生错误

在存储的值计算后,对 ConfigurableFileCollection 调用任何变异器方法(即 clear()add()remove() 等)会引发异常。用户和插件作者应调整其代码,以便 ConfigurableFileCollection 上的所有配置都在配置期间(在读取值之前)发生。

删除 ProjectLayout#configurableFiles

请改用 ObjectFactory#fileCollection()

删除 BasePluginConvention.libsDirBasePluginConvention.distsDir

请改用 libsDirectorydistsDirectory 属性。

删除 UnableToDeleteFileException

现有用法应替换为 RuntimeException

Checkstyle 和 PMD 插件中删除的属性

  • configDir getter 和 setter 已从 Checkstle 任务和扩展中删除。请改用 configDirectory 属性。

  • rulePriority getter 和 setter 已从 Pmd 任务和扩展中删除。请改用 rulesMinimumPriority 属性。

distribution 插件中删除 baseName 属性

getBaseName()setBaseName() 方法已从 Distribution 类中删除。客户端应将用法替换为 distributionBaseName 属性。

使用 AbstractTask

使用 AbstractTask 类型或扩展 AbstractTask 类型的任务在 Gradle 6.5 中已弃用,现在在 Gradle 7.0 中已成为错误。您可以改用 DefaultTask

删除 BuildListener.buildStarted(Gradle)

BuildListener.buildStarted(Gradle) 在 Gradle 6.0 中已弃用,现在在 Gradle 7.0 中已删除。请改用 BuildListener.beforeSettings(Settings)

删除未使用的 StartParameter API

自 Gradle 5.0 起不再可以通过命令行选项使用的以下 API 现已删除:StartParameter.useEmptySettings()StartParameter.isUseEmptySettings()StartParameter.setSearchUpwards(boolean)StartParameter.isSearchUpwards()

不再在“master”目录中搜索设置文件

Gradle 不再支持在同级目录中名为 master 的目录中发现设置文件。如果您的构建仍使用此弃用功能,请考虑重构构建以使根目录与项目层次结构的物理根目录匹配。您可以在用户手册中找到有关 如何构建 Gradle 构建构建组合 的更多信息。或者,您仍然可以通过仅使用 任务的全限定路径master 目录调用构建来运行此类构建中的任务。

modularity.inferModulePath 默认值为“true”

编译测试执行 现在会自动适用于通过包含 module-info.java 文件来定义模块的任何源集。通常,这是您需要的行为。如果在手动配置模块路径或为其使用第三方插件的情况下,这会造成问题,您仍然可以通过在 java 扩展或各个任务上将 modularity.inferModulePath 设置为 false 来选择退出。

删除 ValidateTaskProperties

ValidateTaskProperties 任务已被删除,并由 ValidatePlugins 任务替换。

删除 ImmutableFileCollection

ImmutableFileCollection 类型已被删除。改为使用 工厂方法。可以通过 Project.layout 获取对项目布局的句柄。

删除 ComponentSelectionReason.getDescription

方法 ComponentSelectionReason.getDescription 已被删除。它已被 ComponentSelectionReason.getDescriptions 替换,后者返回 ComponentSelectionDescriptor 列表,每个列表都有一个 getDescription

删除域对象集合构造函数

以下已弃用的构造函数已被删除

  • DefaultNamedDomainObjectList(Class, Instantiator, Namer)

  • DefaultNamedDomainObjectSet(Class, Instantiator)

  • DefaultPolymorphicDomainObjectContainer(Class, Instantiator)

  • FactoryNamedDomainObjectContainer(Class, Instantiator, NamedDomainObjectFactory)

删除任意本地缓存配置

现在需要通过 BuildCacheConfiguration.local() 来完成本地构建缓存配置。

删除 DefaultVersionSelectorScheme 构造函数

此内部 API 在插件中使用,其中包括 Nebula 插件,并且已在 Gradle 5.x 时间表中弃用,现已删除。最新插件版本不应再引用它。

现在,在 checkstyle 插件上设置 config_loc 配置属性是一个错误

checkstyle 插件现在对于以下配置失败

checkstyle {
    configProperties['config_loc'] = file("path/to/checkstyle-config-dir")
}

构建应该使用 checkstyle 块声明 checkstyle 配置

checkstyle {
    configDirectory = file("path/to/checkstyle-config-dir")
}

现在,在生产者完成之前查询提供程序的映射值是一个错误

Gradle 6.x 会警告用户错误的行为,然后返回一个可能不正确的提供程序值。从 7.0 开始,相同的情况将产生一个错误。插件和构建脚本应该调整为在任务完成后查询提供程序的映射值,例如任务输出属性。

现在,任务验证问题是错误

Gradle 6.0 开始警告有关任务定义的问题(例如,错误定义的输入或输出)。对于 Gradle 7.0,这些警告现在是错误,并且将导致构建失败。

当与本地项目发生严格版本冲突时,行为发生改变

以前的 Gradle 版本在特定配置中关于冲突解决的行为不一致:- 您的项目声明对已发布模块的严格依赖(例如,com.mycompany:some-module:1.2!!,其中 1.2!! 是对 1.2 的严格依赖的简写)- 您的构建实际上以更高版本提供 com.mycompany:some-module

以前的 Gradle 版本会成功,选择项目依赖,尽管有严格的约束。从 Gradle 7 开始,这将触发依赖解析失败。

有关更多背景信息,请参阅 此问题

弃用

任务之间的依赖关系丢失

有一个任务在某个位置生成输出,而另一个任务通过引用该位置作为输入来使用该位置,而消费者任务不依赖于生产者任务,这是不推荐的做法。解决此问题的办法是 从消费者添加对生产者的依赖

重复策略

现在,当复制操作(或使用 org.gradle.api.file.CopySpec 的任何操作)遇到重复条目并且未设置重复策略时,Gradle 7 会失败。有关详细信息,请参阅 CopySpec 文档

从 6.8 及更早版本升级

从 6.8 到 6.9 没有升级说明,因为 6.9 仅包含错误修复。

从 6.7 及更早版本升级

潜在的重大更改

Toolchain API 现标记为 @NonNull

org.gradle.jvm.toolchain 中支持 Java Toolchain 功能的 API 现标记为 @NonNull

这可能会影响 Kotlin 消费者,其中 API 的返回类型不再可为空。

默认工具集成版本更新

捆绑 Gradle 依赖项更新

  • Kotlin 已更新至 Kotlin 1.4.20。请注意,Gradle 脚本仍使用 Kotlin 1.3 语言。

  • Apache Ant 已更新至 1.10.9 以修复 CVE-2020-11979

导入 Eclipse 的项目现包含自定义源集类路径

以前,Eclipse 导入的项目仅包含主源集和测试源集的依赖项。自定义源集的编译和运行时类路径被忽略。

自 Gradle 6.8 起,导入 Eclipse 的项目包含构建定义的每个源集的编译和运行时类路径。

SourceTask 不再对空目录敏感

以前,在最新检查和为 SourceTask 中声明的源计算构建缓存密钥期间,空目录会被考虑在内。这意味着,包含空目录的源树和不包含空目录的相同源树会被视为不同的源,即使任务会生成相同的输出。在 Gradle 6.8 中,SourceTask 现在在执行最新检查和构建缓存密钥计算时会忽略空目录。在绝大多数情况下,这是所需的行为,但任务可能会扩展 SourceTask,但在源中存在空目录时也会生成不同的输出。对于存在此问题的任务,您可以公开一个单独的属性,不带 @IgnoreEmptyDirectories 注释,以捕获这些更改

@InputFiles
@SkipWhenEmpty
@PathSensitive(PathSensitivity.ABSOLUTE)
public FileTree getSourcesWithEmptyDirectories() {
    return super.getSource()
}

对发布的更改

发布对强制平台有依赖关系的组件现在会触发验证错误,防止意外发布不良元数据:强制平台用例应仅限于应用程序,而不是可以从其他库或应用程序中使用的内容。

如果您出于某种原因仍希望发布对强制平台有依赖关系的组件,则可以按照 文档 禁用验证。

在执行阶段更改默认排除项

Gradle 的文件树应用一些默认排除模式以方便起见 - 实际上与 Ant 中的默认模式相同。有关更多信息,请参阅 用户手册。有时,Ant 的默认排除项会造成问题,例如当您想在存档文件中包含 .gitignore 时。

在执行阶段更改 Gradle 的默认排除项可能会导致最新检查出现正确性问题。因此,您只允许在设置脚本中更改 Gradle 的默认排除项,有关示例,请参阅 用户手册

弃用

引用包含构建中的任务

已弃用在 mustRunAftershouldRunAfterfinalizedBy 任务方法中直接引用包含构建中的任务。应使用 mustRunAftershouldRunAfter 指定的任务顺序以及 finalizedBy 指定的终结器,用于构建中的任务顺序。如果您碰巧使用上述方法定义了跨构建任务顺序,请考虑重构此类构建并将其彼此解耦。

在“master”目录中搜索设置文件

当您的构建依赖于在同级目录中名为 master 的目录中查找设置文件时,Gradle 将发出弃用警告。

如果您的构建使用此功能,请考虑重构构建以使根目录与项目层次结构的物理根目录匹配。

或者,您仍然可以通过仅使用 任务的完全限定路径master 目录调用构建来运行此类构建中的任务。

使用 NamedDomainObjectContainer<T>.invoke(kotlin.Function1) 方法

Gradle Kotlin DSL 扩展已更改为优先使用 Gradle 的 Action<T> 类型而不是 Kotlin 函数类型。

虽然此更改对 Kotlin 客户端应该是透明的,但调用 Kotlin DSL 扩展的 Java 客户端需要更新为使用 Action<T> API。

从 6.6 及更早版本升级

潜在的重大更改

buildSrc 现在可以从根目录看到包含的构建

以前,buildSrc 的构建方式是忽略根构建中的包含构建。

自 Gradle 6.7 起,buildSrc 可以从根构建中看到任何包含的构建。这可能会导致从 buildSrc 中包含构建中的依赖项被替换。如果 buildSrc 需要包含的构建,这还可能会更改某些构建的执行顺序。

更新默认工具集成版本

弃用

在执行阶段更改默认排除项

Gradle 的文件树应用一些默认排除模式以方便起见 - 实际上与 Ant 中的默认模式相同。有关更多信息,请参阅 用户手册。有时,Ant 的默认排除项会造成问题,例如当您想在存档文件中包含 .gitignore 时。

在执行阶段更改 Gradle 的默认排除项会导致正确性问题,并且已弃用。您只允许在设置脚本中更改 Gradle 的默认排除项,请参阅用户手册以获取示例。

直接将配置用作依赖项

Gradle 允许将 Configuration 的实例直接用作依赖项

dependencies {
    implementation(configurations.myConfiguration)
}

此行为现已弃用,因为它令人困惑:人们可能会期望“从属配置”首先得到解析,并将解析结果作为依赖项添加到包含配置中,但事实并非如此。弃用的版本可以用实际行为(即配置继承)替换

configurations.implementation.extendsFrom(configurations.myConfiguration)

从 6.5 及更早版本升级

潜在破坏性更改

更新捆绑的 Gradle 依赖项

依赖项替换和变体感知依赖项解析

在依赖项替换中添加对表达变体支持的支持时,一个错误修复引入了某些构建可能依赖的行为更改。以前,替换的依赖项仍将使用原始选择器的属性,而不是替换选择器的属性。

有了此更改,围绕具有更丰富选择器的依赖项(例如平台依赖项)的现有替换将不再像以前那样工作。必须在目标选择器中定义变体感知部分。

如果您

  • 依赖于平台,例如 implementation platform("org:platform:1.0")

  • 如果您在依赖项上指定属性,则会受到此更改的影响

  • 并且您对这些依赖项使用解析规则

如果您受到影响,请参阅文档以解决问题。

弃用

Gradle 6.6 中没有进行任何弃用。

从 6.4 及更早版本升级

弃用

内部类 AbstractTask 已弃用

AbstractTask 是在公共 API 中可见的内部类,作为公共类型 DefaultTask 的超类。AbstractTask 将在 Gradle 7.0 中移除,以下内容在 Gradle 6.5 中已弃用

  • 注册类型为 AbstractTaskTaskInternal 的任务。您可以从任务注册中移除任务类型,Gradle 将改用 DefaultTask

  • 注册类型为 AbstractTask 的子类但不是 DefaultTask 的子类的任务。您可以将任务类型更改为扩展 DefaultTask

  • 在插件代码或构建脚本中使用类 AbstractTask。您可以将代码更改为改用 DefaultTask

从 6.3 及更早版本升级

潜在的不兼容更改

PMD 插件默认情况下需要 PMD 6.0.0 或更高版本

Gradle 6.4 默认启用了增量分析。增量分析仅在 PMD 6.0.0 或更高版本中可用。如果您想使用较旧的 PMD 版本,则需要禁用增量分析

pmd {
    incrementalAnalysis = false
}

依赖项锁定中的更改

在 Gradle 6.4 中,依赖项锁定 LockMode 的孵化 API 已更改。现在通过 Property<LockMode> 设置值,而不是直接设置器。这意味着必须为 Kotlin DSL 更新设置值符号

dependencyLocking {
    lockMode.set(LockMode.STRICT)
}

Groovy DSL 的用户不应该受到影响,因为符号 lockMode = LockMode.STRICT 仍然有效。

已发布元数据中的 Java 版本

如果使用 Gradle 模块元数据发布 Java 库,则它支持的 Java 版本信息将编码在 org.gradle.jvm.version 属性中。默认情况下,此属性设置为你在 java.targetCompatibility 中配置的内容。如果未配置,则将其设置为运行 Gradle 的当前 Java 版本。更改特定编译任务的版本(例如 javaCompile.targetCompatibility)不会对该属性产生影响,如果未手动调整该属性,则会导致错误信息。此问题现已修复,该属性默认为与生成已发布 jar 的源关联的编译任务的设置。

具有自定义布局的 Ivy 存储库

从 6.0 到 6.3.x 的 Gradle 版本在自定义存储库布局的 Ivy 存储库上发布时可能会生成错误的 Gradle 模块元数据。从 6.4 开始,如果检测到你在使用自定义存储库布局,Gradle 将不再发布 Gradle 模块元数据。

新属性可能会在构建脚本中隐藏变量

此版本在不同位置引入了几个新属性:mainClassmainModulemodularity。由于这些是十分通用的名称,因此您有可能在构建脚本中将其中一个用作变量名称。然后,新属性可能会以不需要的方式覆盖您的某个变量,从而导致在访问属性而不是具有相同名称的局部变量时构建失败。您可以通过重命名构建脚本中的相应变量来修复它。

受影响的是 application {}java {} 配置块内的配置代码,project.javaexec {} 内的 Java 执行设置,以及各种任务配置(JavaExecCreateStartScriptsJavaCompileTestJavadoc)。

弃用

Gradle 6.3 和 6.4 之间没有弃用。

从 6.2 及更早版本升级

潜在的破坏性更改

IDEA 中可用的依赖项减少

Gradle 不再将注释处理器类路径作为 IDEA 中提供的依赖项包含在内。IDEA 在编译时看到的依赖项与 Gradle 在解析编译类路径(名为 compileClasspath 的配置)后看到的依赖项相同。这可以防止注释处理器依赖项泄漏到项目的代码中。

在 Gradle 引入 增量注释处理支持 之前,IDEA 要求所有注释处理器都位于编译类路径上,以便能够在 IDEA 中编译时运行注释处理。这不再是必需的,因为 Gradle 有一个单独的 注释处理器类路径。当导入带有注释处理器的 Gradle 项目时,注释处理器的依赖项不会添加到 IDEA 模块的类路径中。

捆绑的 Gradle 依赖项更新

默认工具集成版本的更新

某些 32 位操作系统已移除富控制台支持

Gradle 6.3 不支持 32 位 Unix 系统和旧版 FreeBSD(低于 FreeBSD 10)的 富控制台。Microsoft Windows 32 位不受影响。

Gradle 将继续在 32 位系统上构建项目,但不再显示富控制台。

弃用

使用 default 和 archives 配置

几乎每个 Gradle 项目都有 defaultarchives 配置,它们由 base 插件添加。在使用 变体感知依赖管理新发布插件 的现代 Gradle 构建中不再使用这些配置。

虽然这些配置目前仍保留在 Gradle 中以保持向后兼容性,但现在不建议使用它们来声明依赖项或解析依赖项。

解析这些配置从来都不是预期用例,并且只有在早期 Gradle 版本中才有可能,因为在早期 Gradle 版本中每个配置都是可解析的。对于声明依赖项,请使用您所用插件提供的配置,例如 Java Library 插件

从 6.1 及更早版本升级

潜在的重大更改

编译和运行时类路径现在默认请求库变体

JVM 项目中的类路径现在明确请求 org.gradle.category=library 属性。如果无法使用某个库,这将导致更清晰的错误消息。例如,当库不支持所需的 Java 版本时。实际效果是,现在所有 平台依赖项 都必须声明为平台依赖项。以前,当本地平台或使用 Gradle 模块元数据发布的平台省略 platform() 关键字时,平台依赖项也偶然起作用。

项目根 gradle.properties 中的属性泄漏到 buildSrc 和包含的构建中

Gradle 6.2 和 Gradle 6.2.1 中存在一个回归,导致在项目根 gradle.properties 文件中设置的 Gradle 属性泄漏到 buildSrc 构建和根包含的任何构建中。

如果 buildSrc 构建或包含的构建突然发现来自项目根 gradle.properties 文件的属性的意外或不兼容的值,则可能会导致构建开始失败。

此回归已在 Gradle 6.2.2 中修复。

弃用

Gradle 6.1 和 6.2 之间没有弃用。

从 6.0 及更早版本升级

弃用

在任务完成之前查询任务的映射输出属性

在任务完成之前查询映射输出属性的值可能会导致奇怪的构建失败,因为它表明可能会错误地使用过时的或不存在的输出。此行为已弃用,并将发出弃用警告。这将在 Gradle 7.0 中成为错误。

以下示例演示了此问题,其中在 Producer 执行之前解析 Producer 的输出文件

class Consumer extends DefaultTask {
    @Input
    final Property<Integer> threadPoolSize = ...
}

class Producer extends DefaultTask {
    @OutputFile
    final RegularFileProperty outputFile = ...
}

// threadPoolSize is read from the producer's outputFile
consumer.threadPoolSize = producer.outputFile.map { it.text.toInteger() }

// Emits deprecation warning
println("thread pool size = " + consumer.threadPoolSize.get())

如果在 producer 完成之前查询 consumer.threadPoolSize 的值,将产生弃用警告,因为尚未生成输出文件。

已中止的方法

以下方法已中止,不应再使用。它们将在 Gradle 7.0 中删除。

  • BasePluginConvention.setProject(ProjectInternal)

  • BasePluginConvention.getProject()

  • StartParameter.useEmptySettings()

  • StartParameter.isUseEmptySettings()

备用 JVM 插件(又称“软件模型”)

在 Gradle 2.x 中,引入了一组基于“软件模型”的 Java 和 Scala 开发备用插件作为一项实验。这些插件现已弃用,最终将被移除。如果您仍在使用其中一个旧插件(java-langscala-langjvm-componentjvm-resourcesjunit-test-suite),请参阅 构建 Java 和 JVM 项目 中的文档,以确定哪些稳定的 JVM 插件适合您的项目。

潜在的重大更改

ProjectLayout 不再作为服务提供给工作器操作

在 Gradle 6.0 中,ProjectLayout 服务通过服务注入提供给工作器操作。此服务允许可变状态泄漏到工作器操作中,并引入了一种方法,使依赖项在工作器操作中保持未声明状态。

ProjectLayout 已从可用服务中移除。使用 ProjectLayout 的工作器操作应改为注入 projectDirectorybuildDirectory 作为参数。

更新默认工具集成版本

发布 Spring Boot 应用程序

从 Gradle 6.2 开始,Gradle 在上传之前会执行健全性检查,以确保您不会上传陈旧文件(由其他构建生成的)。这会给使用 components.java 组件上传的 Spring Boot 应用程序带来问题

Artifact my-application-0.0.1-SNAPSHOT.jar wasn't produced by this build.

这是因为 Spring Boot 应用程序禁用了主 jar 任务,而该组件希望它存在。由于 bootJar 任务默认使用与主 jar 任务相同的文件,因此 Gradle 的早期版本将

  • 发布陈旧的 bootJar 工件

  • 或在之前未调用 bootJar 任务时失败

解决方法是告诉 Gradle 要上传什么。如果您要上传 bootJar,则需要配置传出配置以执行此操作

configurations {
   [apiElements, runtimeElements].each {
       it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
       it.outgoing.artifact(bootJar)
   }
}

或者,您可能希望重新启用 jar 任务,并使用不同的分类器添加 bootJar

jar {
   enabled = true
}

bootJar {
   classifier = 'application'
}