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

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

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

    Deprecations View in a Build Scan

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

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

  2. 更新您的插件。

    某些插件将在此新版 Gradle 中中断,例如因为它们使用了已移除或更改的内部 API。上一步将通过在插件尝试使用 API 的已弃用部分时发出弃用警告来帮助您识别潜在问题。

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

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

从 6.9 及更早版本升级

IDE 集成中的更改

IDEA 模型中的更改

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

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

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

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

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

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

jcenter() 便利方法现已弃用

JFrog 于 2021 年 2 月宣布 JCenter 仓库停用。许多 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 插件

使用 Gradle 7.0 构建的插件在使用 gradleApi()localGroovy() 时,其 classpath 中现在将包含 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 构建脚本的数量,您可能会在首次编译构建脚本或更改构建脚本的 classpath 时注意到性能下降。这是由于 Groovy 3 解析器的性能较慢,但 Groovy 团队已意识到此问题并正在努力缓解此下降。

总的来说,我们也在研究如何提高 Groovy DSL 和 Kotlin DSL 的构建脚本编译性能。

遇到“Could not find method X for arguments Y on DefaultDependencyHandler”

虽然以下错误最初看起来像编译错误,但实际上是由于删除了特定的 `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 Library 插件文档来了解新配置的优点以及在 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 的构建后尝试删除根项目目录时出现错误。例如,结合 JUnit 的 @TempDir 扩展或 TemporaryFolder 规则使用 TestKit 的测试可能会遇到此问题。为避免这些文件锁问题,TestKit 会在 Windows 上通过 GradleRunner 执行的构建中禁用文件系统监视。如果您想覆盖默认行为,可以通过将 --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 会产生错误。

要解决此错误,请为构建创建 settings.gradle(.kts) 文件

例外情况是使用 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

在 Gradle 6.5 中,使用 AbstractTask 类型或扩展 AbstractTask 的类型注册任务已被弃用,现在在 Gradle 7.0 中是一个错误。您可以改用 DefaultTask

移除 BuildListener.buildStarted(Gradle)

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

移除未使用的 StartParameter API

以下 API 自 Gradle 5.0 以来已无法通过命令行选项使用,现已移除: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 是一个内部类,它作为公共类型 DefaultTask 的超类在公共 API 上可见。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 版本

如果 Java 库通过 Gradle 模块元数据发布,它支持的 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 不再将注解处理器 classpath 作为提供的依赖项包含在 IDEA 中。IDEA 在编译时看到的依赖项与 Gradle 在解析编译 classpath(名为 compileClasspath 的配置)后看到的依赖项相同。这防止了注解处理器依赖项泄漏到项目代码中。

在 Gradle 引入增量注解处理支持之前,IDEA 要求所有注解处理器都在编译 classpath 上,才能在 IDEA 中编译时运行注解处理。现在这已不再需要,因为 Gradle 有一个单独的注解处理器 classpath。当导入包含注解处理器的 Gradle 项目时,注解处理器的依赖项不会添加到 IDEA 模块的 classpath 中。

捆绑的 Gradle 依赖项更新

默认工具集成版本的更新

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

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

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

弃用

使用默认和归档配置

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

尽管这些配置为了向后兼容性目前仍保留在 Gradle 中,但使用它们声明依赖项或解析依赖项现已弃用。

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

从 6.1 及更早版本升级

潜在的重大更改

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

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

项目根目录 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 中成为错误。

以下示例演示了此问题,其中生产者输出文件在生产者执行之前被解析

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 在上传前执行完整性检查,以确保您不会上传过时文件(由其他构建生成的文件)。这导致 Spring Boot 应用程序在使用 components.java 组件上传时出现问题

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'
}