本章提供将您的 Gradle 5.x 构建迁移到 Gradle 6.0 所需的信息。 要从 Gradle 4.x 迁移,请首先完成4.x 到 5.0 指南

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

  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 6.0 以将项目更新到 6.0。

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

从 5.6 及更早版本升级

弃用

不应再使用 compileruntime 配置声明依赖项

Gradle 3.4以来,Java 生态系统插件中 compileruntime 配置的使用一直不被鼓励。

这些配置用于编译和运行来自 main 源集中的代码。 其他源集创建类似的配置(例如,test 源集的 testCompiletestRuntime),也不应使用。 implementationapicompileOnlyruntimeOnly 配置应用于声明依赖项,而 compileClasspathruntimeClasspath 配置应用于解析依赖项。 请参阅这些配置的关系

旧版发布系统已弃用,并被 *-publish 插件取代

uploadArchives 任务和 maven 插件已弃用。

用户应通过使用maven-publishivy-publish插件迁移到 Gradle 的发布系统。 这些插件自 Gradle 4.8 以来一直稳定。

发布系统也是确保发布Gradle 模块元数据的唯一方法。

任务问题发出弃用警告

当 Gradle 检测到任务定义存在问题(例如,错误定义的输入或输出)时,它将在控制台上显示以下消息

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org.cn/6.0/userguide/command_line_interface.html#sec:command_line_warnings

弃用警告显示在构建扫描中,用于每个构建,无论使用什么命令行开关。

当使用 --warning-mode all 执行构建时,将显示单个警告

> Task :myTask
Property 'inputDirectory' is declared without normalization specified. Properties of cacheable work must declare their normalization via @PathSensitive, @Classpath or @CompileClasspath. Defaulting to PathSensitivity.ABSOLUTE. This behavior is scheduled to be removed in Gradle 7.0.
Property 'outputFile' is not annotated with an input or output annotation. This behavior is scheduled to be removed in Gradle 7.0.

如果您拥有相关任务的代码,您可以按照建议修复它们。 您还可以使用 --stacktrace 查看每个警告来自代码中的哪个位置。

否则,您需要将问题报告给相关任务或插件的维护者。

增量任务的旧 API,IncrementalTaskInputs,已被弃用

在 Gradle 5.4 中,我们引入了一个新的 API 来实现增量任务InputChanges。 基于 IncrementalTaskInputs 的旧 API 已被弃用。

强制依赖项

在第一级依赖项上使用 force = true 强制依赖项版本已被弃用。

Force 既存在语义问题又存在排序问题,可以通过使用严格版本约束来避免。

在 Gradle 5.0 中,我们删除了 --no-search-upward CLI 参数。

StartParameter 中相关的 API(如 isSearchUpwards())现在已弃用。

API BuildListener.buildStartedGradle.buildStarted 已被弃用

这些方法目前无法按预期工作,因为在构建开始后永远不会调用回调。

弃用这些方法是为了避免混淆。

Copy 或归档任务的隐式重复策略已被弃用

归档任务 TarZip 默认允许在创建的归档文件中存在同一路径的多个条目。 这可能会导致“严重无效的 zip 文件”,可能会触发 zip 炸弹检测

为了防止意外发生这种情况,在创建归档文件时遇到重复项现在会生成弃用消息,并且从 Gradle 7.0 开始将使构建失败。

Copy 任务也很乐意将具有相同相对路径的多个源复制到目标目录。 此行为也已被弃用。

如果您想允许重复项,您可以显式指定

task archive(type: Zip) {
    duplicatesStrategy = DuplicatesStrategy.INCLUDE // allow duplicates
    ...
}

在没有设置文件的情况下执行 Gradle 已被弃用

Gradle 构建由当前目录或父目录中的 settings.gradle[.kts] 文件定义。 如果没有设置文件,则 Gradle 构建未定义,并将发出弃用警告。

在 Gradle 7.0 中,Gradle 将仅允许您使用未定义的构建调用 init 任务或诊断命令行标志,例如 --version

在已评估的项目上调用 Project.afterEvaluate 已被弃用

一旦项目被评估,Gradle 将忽略传递给 Project#afterEvaluate 的所有配置,并发出弃用警告。 这种情况将在 Gradle 7.0 中变为错误。

已弃用的插件

以下捆绑插件从未发布,将在 Gradle 的下一个主要版本中删除

  • org.gradle.coffeescript-base

  • org.gradle.envjs

  • org.gradle.javascript-base

  • org.gradle.jshint

  • org.gradle.rhino

其中一些插件可能在插件门户上有替代品。

潜在的重大更改

不再支持 Android Gradle 插件 3.3 及更早版本

Gradle 6.0 支持 Android Gradle 插件版本 3.4 及更高版本。

不再支持构建扫描插件 2.x

对于 Gradle 6,构建扫描插件的使用必须替换为 Develocity 插件。 这也需要更改插件的应用方式。 请参阅 https://gradle.com/help/gradle-6-build-scan-plugin 以获取更多信息。

捆绑的 Gradle 依赖项的更新

默认集成版本的更新

复合构建中构建和任务名称的更改

以前,Gradle 使用根项目的名称作为包含构建的构建名称。 现在,使用构建的根目录的名称,如果根项目名称不同,则不考虑根项目名称。 如果通过设置文件包含构建,则可以指定不同的构建名称。

includeBuild("some-other-build") {
    name = "another-name"
}

以前的行为是有问题的,因为它导致在构建期间的不同时间使用不同的名称。

buildSrc 现在保留作为项目和子项目构建名称

以前,Gradle 不阻止对多项目构建的子项目或作为包含构建的名称使用名称“buildSrc”。 现在,这是不允许的。 名称“buildSrc”现在保留用于构建额外构建逻辑的传统 buildSrc 项目。

buildSrc 的典型用法不受此更改的影响。 仅当您的设置文件指定 include("buildSrc")includeBuild("buildSrc") 时,您才会受到影响。

Scala Zinc 编译器

Zinc 编译器已升级到 1.3.0 版本。 Gradle 不再支持为 Scala 2.9 构建。

Gradle 支持的最低 Zinc 编译器版本为 1.2.0,最大测试版本为 1.3.0。

为了更容易选择 Zinc 编译器的版本,您现在可以配置 zincVersion 属性

scala {
    zincVersion = "1.2.1"
}

请删除您添加到 zinc 配置中的任何显式依赖项,并改用此属性。 如果您尝试使用 com.typesafe.zinc:zinc 依赖项,Gradle 将切换到新的 Zinc 实现。

本地构建缓存始终是目录缓存

过去,可以使用任何构建缓存实现作为 local 缓存。 这不再允许,因为本地缓存必须始终是 DirectoryBuildCache

使用 DirectoryBuildCache 以外的任何类作为类型调用 BuildCacheConfiguration.local(Class) 将使构建失败。 使用 DirectoryBuildCache 类型调用这些方法将产生弃用警告。

请改用 getLocal()local(Action)

未能打包或解包缓存结果现在将使构建失败

过去,当 Gradle 在打包缓存任务的结果时遇到问题时,Gradle 会忽略该问题并继续运行构建。

当遇到损坏的缓存工件时,Gradle 会删除已解包的任何内容并重新执行任务,以确保构建有机会成功。

虽然此行为旨在使构建成功,但这产生了隐藏问题的负面影响,并导致缓存性能降低。

在 Gradle 6.0 中,打包和解包错误都会导致构建失败,以便更容易地发现这些问题。

buildSrc 项目自动使用构建缓存配置

以前,为了将构建缓存用于 buildSrc 构建,您需要在 buildSrc 构建中复制您的构建缓存配置。 现在,它自动使用顶级设置脚本定义的构建缓存配置。

Gradle 模块元数据始终发布

Gradle 模块元数据于 Gradle 5.3 正式推出,Gradle 模块元数据旨在解决多年来困扰依赖管理的许多问题,尤其是在 Java 生态系统中,但不限于此。

使用 Gradle 6.0,默认启用 Gradle 模块元数据。

这意味着,如果您正在使用 Gradle 发布库并使用maven-publishivy-publish插件,则 Gradle 模块元数据文件始终除了传统元数据之外还发布。

传统元数据文件将包含一个标记,以便 Gradle 知道有额外的元数据要使用。

Gradle 模块元数据具有更严格的验证

发布 Gradle 模块元数据时,会验证以下规则

这些都记录在规范中。

默认情况下,不再为没有元数据的工件查询 Maven 或 Ivy 仓库

如果 Gradle 无法在 repositories { } 部分中定义的仓库中找到模块的元数据文件(.pomivy.xml),它现在会假设该模块在该仓库中不存在。

对于动态版本,相应模块的 maven-metadata.xml 需要存在于 Maven 仓库中。

以前,Gradle 也会查找默认工件 (.jar)。 当使用多个仓库时,此行为通常会导致大量不必要的请求,从而减慢构建速度。

您可以通过添加 artifact() 元数据源为选定的仓库选择旧行为。

更改 pom packaging 属性不再更改工件扩展名

以前,如果 pom 打包不是 jarejbbundlemaven-plugin,则在发布到 Maven 仓库时,主工件的扩展名会更改为与 pom 打包匹配。

此行为导致 Gradle 模块元数据损坏,并且由于处理不同的打包类型而难以理解。

构建作者可以在创建工件时更改工件名称,以获得与以前相同的结果 — 例如,通过显式设置 jar.archiveExtension.set(pomPackaging)

为 Java 库发布的 ivy.xml 包含更多信息

ivy-publish 插件中,对生成更正确的 ivy.xml 元数据进行了一些修复。

因此,ivy.xml 文件的内部结构发生了变化。 runtime 配置现在包含更多信息,这对应于 Java 库的 runtimeElements 变体。 default 配置应产生与以前相同的结果。

一般来说,建议用户从 ivy.xml 迁移到新的 Gradle 模块元数据格式。

buildSrc 中的类不再对设置脚本可见

以前,buildSrc 项目在应用项目的设置脚本之前构建,并且其类在脚本中可见。 现在,buildSrc 在设置脚本之后构建,并且其类对设置脚本不可见。 buildSrc 类对项目构建脚本和脚本插件仍然可见。

自定义逻辑可以从设置脚本中使用,方法是声明外部依赖项

设置脚本中的 pluginManagement 块现在是隔离的

以前,设置脚本中的任何 pluginManagement {} 块都在脚本的正常执行期间执行。

现在,它们的执行方式与 buildscript {}plugins {} 类似,更早执行。 这意味着此类块内的代码不能引用脚本中其他位置声明的任何内容。

进行此更改是为了在解析设置脚本本身的插件时也可以应用 pluginManagement 配置。

在设置脚本中加载的插件和类对项目脚本和 buildSrc 可见

以前,通过使用 buildscript {} 添加到设置脚本的任何类在脚本外部都不可见。 现在,它们对所有项目构建脚本都可见。

它们对于 buildSrc 构建脚本及其设置脚本也是可见的。

进行此更改是为了应用于设置脚本的插件可以将逻辑贡献给整个构建。

插件验证更改

  • validateTaskProperties 任务现在已弃用,请改用 validatePlugins。 新名称更好地反映了它还验证工件转换参数和其他非属性定义的事实。

  • ValidateTaskProperties 类型已替换为 ValidatePlugins

  • setClasses() 方法现在已删除。 请改用 getClasses().setFrom()

  • setClasspath() 方法也已删除。 请改用 getClasspath().setFrom()

  • failOnWarning 选项现在默认启用。

  • 以下任务验证错误现在在运行时使构建失败,并提升为 ValidatePlugins 的错误

    • 任务属性使用不允许用于任务的属性注释进行注释,例如 @InputArtifact

使用 embedded-kotlin 插件现在需要仓库

就像使用 kotlin-dsl 插件一样,现在如果应用 embedded-kotlin 插件,则需要声明一个可以找到 Kotlin 依赖项的仓库。

plugins {
    `embedded-kotlin`
}

repositories {
    mavenCentral()
}

Kotlin DSL IDE 支持现在需要 Kotlin IntelliJ 插件 >= 1.3.50

对于早于 1.3.50 的 Kotlin IntelliJ 插件版本,当 Gradle JVM 设置为与 Project SDK 中的版本不同的版本时,Kotlin DSL 脚本将被错误地突出显示。 只需将您的 IDE 插件升级到 >= 1.3.50 版本即可恢复正确的 Kotlin DSL 脚本突出显示行为。

Kotlin DSL 脚本基本类型不再扩展 ProjectSettingsGradle

在以前的版本中,Kotlin DSL 脚本被编译为实现三个核心 Gradle 配置接口之一的类,以便隐式地将其 API 公开给脚本。 项目脚本的 org.gradle.api.Project,设置脚本的 org.gradle.api.initialization.Settings 和 init 脚本的 org.gradle.api.invocation.Gradle

让脚本实例实现它应该配置的模型对象的核心 Gradle 接口很方便,因为它使模型对象 API 立即对脚本主体可用,但这也是一个谎言,每当脚本本身代替模型对象使用时,都可能引起各种麻烦,项目脚本不是一个合适的 Project 实例,仅仅因为它实现了核心 Project 接口,并且设置和 init 脚本也是如此。

在 6.0 中,所有 Kotlin DSL 脚本都编译为实现新引入的 org.gradle.kotlin.dsl.KotlinScript 接口的类,相应的模型对象现在作为脚本主体中的隐式接收器可用。 换句话说,项目脚本的行为就像脚本主体包含在 with(project) { …​ } 块中一样,设置脚本的行为就像脚本主体包含在 with(settings) { …​ } 块中一样,而 init 脚本的行为就像脚本主体包含在 with(gradle) { …​ } 块中一样。 这意味着相应的模型对象也作为脚本主体中的属性可用,项目脚本的 project 属性,设置脚本的 settings 属性和 init 脚本的 gradle 属性。

作为更改的一部分,设置脚本不再实现 SettingsScriptApi 接口,init 脚本不再实现 InitScriptApi 接口。 它们应替换为相应的模型对象接口,SettingsGradle

Javadoc 和 Groovydoc 默认不包含时间戳

生成文档中的时间戳的实际用途非常有限,但是它们使得无法进行可重复的文档构建。 因此,JavadocGroovydoc 任务现在配置为默认不再包含时间戳。

Checkstyle 忽略用户提供的“config_loc”属性

Gradle 始终使用 configDirectory 作为运行 Checkstyle 时“config_loc”的值。

新的 Tooling API 进度事件

在 Gradle 6.0 中,我们引入了一个新的进度事件 (org.gradle.tooling.events.test.TestOutputEvent) 以公开测试执行的输出。 这个新的事件打破了具有 StartEvent-FinishEvent 对来表示进度的约定。 TaskOutputEvent 是一个简单的 ProgressEvent

任务容器行为的更改

任务容器上的以下已弃用方法现在会导致错误

  • TaskContainer.add()

  • TaskContainer.addAll()

  • TaskContainer.remove()

  • TaskContainer.removeAll()

  • TaskContainer.retainAll()

  • TaskContainer.clear()

  • TaskContainer.iterator().remove()

此外,以下已弃用的功能现在会导致错误

  • 替换已实现的任务。

  • 使用不兼容的类型替换已注册(未实现)的任务。 兼容类型是相同类型或已注册类型的子类型。

  • 替换从未注册的任务。

DefaultTaskProjectLayout 上的方法已替换为 ObjectFactory

请改用 ObjectFactory.fileProperty() 而不是以下现在已删除的方法

  • DefaultTask.newInputFile()

  • DefaultTask.newOutputFile()

  • ProjectLayout.fileProperty()

请改用 ObjectFactory.directoryProperty() 而不是以下现在已删除的方法

  • DefaultTask.newInputDirectory()

  • DefaultTask.newOutputDirectory()

  • ProjectLayout.directoryProperty()

注解 @Nullable 已删除

org.gradle.api.Nullable 注解类型已删除。 请改用 JSR-305 中的 javax.annotation.Nullable

FindBugs 插件已删除

已弃用的 FindBugs 插件已删除。 作为替代方案,您可以使用SpotBugs 插件,该插件来自Gradle 插件门户

JDepend 插件已删除

已弃用的 JDepend 插件已删除。 Gradle 插件门户上提供了许多社区提供的用于代码和架构分析的插件。

OSGI 插件已删除

已弃用的 OSGI 插件已删除。 Gradle 插件门户上提供了许多社区提供的 OSGI 插件。

announce 和 build-announcements 插件已被移除

已弃用的 announce 和 build-announcements 插件已被移除。在 Gradle 插件门户 上有许多社区提供的插件可用于发送通知。

Compare Gradle Builds 插件已被移除

已弃用的 Compare Gradle Builds 插件已被移除。请使用 build scans 进行构建分析和比较。

Play 插件已被移除

已弃用的 Play 插件已被移除。一个外部替代品,Play Framework 插件,可从插件门户获取。

方法 AbstractCompile.compile() 方法已被移除

抽象方法 compile() 不再由 AbstractCompile 声明。

扩展 AbstractCompile 的任务可以实现它们自己的带有他们选择的名称的 @TaskAction 方法。

他们也可以自由添加一个使用带有 InputChanges 参数的 @TaskAction 注解的方法,而无需实现一个无参数的方法。

其他已弃用的行为和 API

  • org.gradle.util.internal.GUtil.savePropertiesNoDateComment 已被移除。此内部方法没有公共替代品。

  • 已弃用的类 org.gradle.api.tasks.compile.CompilerArgumentProvider 已被移除。请使用 org.gradle.process.CommandLineArgumentProvider 代替。

  • 已弃用的类 org.gradle.api.ConventionProperty 已被移除。请使用 Providers 代替约定属性。

  • 已弃用的类 org.gradle.reporting.DurationFormatter 已被移除。

  • 桥接方法 org.gradle.api.tasks.TaskInputs.property(String name, @Nullable Object value) 返回 TaskInputs 已被移除。使用此方法的插件必须使用 Gradle 4.3 编译才能在 Gradle 6.0 上工作。

  • 以下 setter 已从 JacocoReportBase 中移除

  • JacocoTaskExtension 上的 append 属性已被移除。现在,对于 Jacoco 代理,append 始终配置为 true。

  • JacocoPlugin 上的 configureDefaultOutputPathForJacocoMerge 方法已被移除。该方法从未打算公开。

  • 耳插件的 deployment descriptor file name 中的文件路径不再被允许。请使用一个简单的名称,例如 application.xml

  • org.gradle.testfixtures.ProjectBuilder 构造函数已被移除。请使用 ProjectBuilder.builder() 代替。

  • 增量 Groovy 编译 启用时,错误的源根配置或为 Groovy 启用 Java 注解现在将导致构建失败。当您想在这些情况下编译时,请禁用增量 Groovy 编译。

  • ComponentSelectionRule 不再可以注入元数据或 ivy 描述符。请使用 ComponentSelection 参数 上的方法代替。

  • 声明一个没有声明输出的 增量任务 现在是一个错误。请声明文件输出或使用 TaskOutputs.upToDateWhen() 代替。

  • getEffectiveAnnotationProcessorPath() 方法已从 JavaCompileScalaCompile 任务中移除。

  • 在任务开始执行后,更改类型为 Property<T> 的任务属性的值现在会导致错误。

  • isLegacyLayout() 方法已从 SourceSetOutput 中移除。

  • TaskInputs.getProperties() 返回的 map 现在是不可修改的。尝试修改它将导致抛出 UnsupportedOperationException

  • 在孵化中的 capabilities resolution API 中有细微的变化,该 API 在 5.6 中引入,也允许基于变体名称进行变体选择

从 5.5 及更早版本升级

弃用

在任务开始执行后更改 ConfigurableFileCollection 任务属性的内容

当任务属性的类型为 ConfigurableFileCollection 时,一旦任务开始执行,属性引用的文件集合将忽略对集合内容所做的更改。这有两个好处。首先,这防止了在任务执行期间意外更改属性值,这可能导致 Gradle 的最新检查和构建缓存查找使用与任务操作所使用的值不同的值。其次,这提高了性能,因为 Gradle 可以计算一次值并缓存结果。

这将在 Gradle 6.0 中变为错误。

创建 SignOperation 实例

直接创建 SignOperation 实例现在已被弃用。相反,应该使用 SigningExtension 的方法来创建这些实例。

这将在 Gradle 6.0 中变为错误。

声明没有输出的增量任务

声明一个没有声明输出的 增量任务 现在已被弃用。请声明文件输出或使用 TaskOutputs.upToDateWhen() 代替。

这将在 Gradle 6.0 中变为错误。

方法 WorkerExecutor.submit() 已被弃用

WorkerExecutor.submit() 方法现在已被弃用。现在应该使用新的 noIsolation()classLoaderIsolation()processIsolation() 方法来提交工作。有关使用这些方法的更多信息,请参阅 关于 Worker API 的章节

WorkerExecutor.submit() 将在 Gradle 8.0 中移除。

潜在的破坏性更改

对于值是 Property 的任务 @Input 属性,任务依赖项会被遵守

以前,对于类型为 Property<T> 的任务 @Input 属性,任务依赖项将被忽略。现在这些依赖项会被遵守,因此可以将任务输出属性附加到任务 @Input 属性。

这可能会在任务依赖关系图中引入意外的循环,其中输出属性的值被映射以生成输入属性的值。

使用不代表任务输出的文件 Provider 声明任务依赖项

以前,可以将不代表任务输出的 Provider<File>Provider<RegularFile>Provider<Directory> 实例传递给 Task.dependsOn()。这些 provider 将被静默忽略。

现在这是一个错误,因为 Gradle 不知道如何构建不是任务输出的文件。

注意,仍然可以将返回文件并代表任务输出的 Provider 传递给 Task.dependsOn(),例如 myTask.dependsOn(jar.archiveFile)myTask.dependsOn(taskProvider.flatMap { it.outputDirectory }),当 Provider 是任务的注解 @OutputFile@OutputDirectory 属性时。

Property 值设置为 null 将使用属性约定

以前,调用 Property.set(null) 将始终将属性的值重置为“未定义”。现在,使用 convention() 方法与属性关联的约定将用于确定属性的值。

增强了对 publishing.publicationspublishing.repositories 名称的验证

仓库和发布名称用于构造发布的任务名称。有可能提供一个名称,该名称将导致无效的任务名称。现在,发布和仓库的名称被限制为 [A-Za-z0-9_\\-.]+

受限的 Worker API 类加载器和进程类路径

Gradle 现在阻止内部依赖项(例如 Guava)泄漏到 Worker API 操作使用的类路径中。这修复了 一个问题,即 worker 需要使用 Gradle 内部也使用的依赖项。

在以前的版本中,有可能依赖这些泄漏的类。依赖于此行为的插件现在将失败。要修复插件,worker 应在其类路径中显式包含所有必需的依赖项。

默认 PMD 版本升级到 6.15.0

PMD 插件 已升级为默认使用 PMD 版本 6.15.0 而不是 6.8.0。

wreulicke 贡献

配置副本具有唯一的名称

以前,配置的所有副本始终具有名称 <OriginConfigurationName>Copy。现在,当创建多个副本时,每个副本都将具有唯一的名称,通过从第二个副本开始添加索引。(例如 CompileOnlyCopy2

Eclipse 的类路径过滤已更改

Gradle 5.6 不再在 Eclipse 模型中提供自定义类路径属性。相反,它为 Eclipse 测试源 提供属性。此更改需要 Buildship 版本 3.1.1 或更高版本。

嵌入式 Kotlin 升级到 1.3.41

现在,使用 Kotlin 1.3.41 编译使用 kotlin-dsl 插件编写的 Gradle Kotlin DSL 脚本和 Gradle 插件。

有关包含的更改的更多信息,请参阅 Kotlin 博客文章更新日志

现在支持的最低 Kotlin Gradle 插件版本为 1.2.31。以前是 1.2.21。

自动功能冲突解决

以前版本的 Gradle 在发生功能冲突时会自动选择具有最高功能版本的模块。从 5.6 开始,这是一种可选行为,可以使用以下方式激活

configurations.all {
   resolutionStrategy.capabilitiesResolution.all { selectHighestVersion() }
}

有关更多选项,请参阅 文档的功能部分

文件删除操作不遵循符号链接目录

当 Gradle 必须出于各种原因删除任务的输出文件时,它不会遵循符号链接目录。符号链接本身将被删除,但链接目录的内容将保持不变。

在 JavaExec 中禁用调试参数解析

Gradle 5.6 引入了一个新的 DSL 元素 (JavaForkOptions.debugOptions(Action<JavaDebugOptions>)) 来配置 fork Java 进程的调试属性。由于此更改,Gradle 不再解析与调试相关的 JVM 参数。因此,如果为进程指定了 -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 参数,则 JavaForkOptions.getDebu() 不再返回 true

Scala 2.9 和 Zinc 编译器

Gradle 不再支持使用 Scala 2.9 构建应用程序。

从 5.4 及更早版本升级

弃用

Play

内置的 Play 插件 已被弃用,将被一个新的 Play Framework 插件 替代,该插件可从插件门户获取。

构建比较

构建比较 插件已被弃用,将在 Gradle 的下一个主要版本中移除。

Build scans 显示了对您的构建更深入的洞察,您可以使用 Develocity 直接比较两个构建的 build-scans。

潜在的破坏性更改

用户提供的 Eclipse 项目名称在冲突时可能会被忽略

通过 EclipseProject.setName(…​) 配置的项目名称在所有情况下都受到 Gradle 和 Buildship 的尊重,即使名称导致冲突和导入/同步错误。

如果 Eclipse 工作区中的其他项目名称发生冲突,Gradle 现在可以对这些名称进行去重。这可能会导致具有用户指定名称的项目使用不同的 Eclipse 项目名称。

即将推出的 3.1.1 版本的 Buildship 是利用此行为所必需的。

Christian Fränkel 贡献

默认 JaCoCo 版本升级到 0.8.4

JaCoCo 插件 已升级为默认使用 JaCoCo 版本 0.8.4 而不是 0.8.3。

Evgeny Mandrikov 贡献

嵌入式 Ant 版本升级到 1.9.14

与 Gradle 一起分发的 Ant 版本已从 1.9.13 升级到 1.9.14

类型 DependencyHandler 现在静态地公开 ExtensionAware

这会影响 Kotlin DSL 构建脚本,这些脚本使用 ExtensionAware 扩展成员,例如 dependencies {} 代码块内的 extra 属性访问器。这些成员的接收者将不再是封闭的 Project 实例,而是 dependencies 对象本身,即最内层的 ExtensionAware 一致性接收者。为了在 dependencies {} 中寻址 Project 额外属性,接收者必须被显式限定,即 project.extra 而不是仅 extra。受影响的扩展还包括 the<T>()configure<T>(T.() → Unit)

改进了依赖项排除的处理

以前版本的 Gradle 在某些复杂的依赖关系图中,当存在大量排除项时,可能会产生错误的结果或随机的依赖项顺序。为了缓解这种情况,已重写计算排除项的算法。在某些罕见的情况下,由于正确性更改,这可能会导致分辨率上的一些差异。

改进了 worker 进程的类路径隔离

当使用 PROCESS 隔离时,由 Worker API 启动的 worker 守护进程的系统类路径已减少到 Gradle 基础设施的最小集合。用户代码仍然被隔离到单独的类加载器中,以将其与 Gradle 运行时隔离。对于使用 worker API 的任务来说,这应该是一个透明的更改,但以前版本的 Gradle 在 worker 进程中混合了用户代码和 Gradle 内部组件。依赖于诸如 java.class.path 系统属性之类的 worker 操作可能会受到影响,因为 java.class.path 现在仅表示 Gradle 内部组件的类路径。

从 5.3 及更早版本升级

弃用

使用自定义本地构建缓存实现

现在不建议对本地构建缓存使用自定义构建缓存实现。未来唯一允许的类型将是 DirectoryBuildCache。对使用自定义构建缓存实现作为远程构建缓存的支持没有变化。

潜在的破坏性更改

通过 googleApis() 配置 Google Hosted Libraries 时使用 HTTPS

可通过 JavaScriptRepositoriesExtension#GOOGLE_APIS_REPO_URL 访问的 Google Hosted Libraries URL 已更改为使用 HTTPS 协议。此更改也影响通过 googleApis() 配置的 Ivy 仓库。

从 5.2 及更早版本升级

潜在的破坏性更改

平台解析中的错误修复

从 Gradle 5.0 到 5.2.1(包括)存在一个错误,其中强制平台可能会包含依赖项而不是约束。每当 POM 文件定义了依赖项和“约束”(通过 <dependencyManagement>)并且您使用了 enforcedPlatform 时,就会发生这种情况。Gradle 5.3 修复了此错误,这意味着如果您依赖于这种损坏的行为,则分辨率结果可能会有所不同。同样,Gradle 5.3 将不再尝试下载 platformenforcedPlatform 依赖项的 jar(因为它们应该只引入约束)。

自动目标 JVM 版本

如果您应用任何 Java 插件,Gradle 现在将尽最大努力选择与正在编译的模块的目标兼容性相匹配的依赖项。实际上,这意味着如果您有一个为 Java 8 构建的模块 A 和一个为 Java 8 构建的模块 B,则不会有任何变化。但是,如果 B 是为 Java 9+ 构建的,那么它不再是二进制兼容的,Gradle 会报错,如下所示

Unable to find a matching variant of project :producer:
  - Variant 'apiElements' capability test:producer:unspecified:
      - Provides org.gradle.dependency.bundling 'external'
      - Required org.gradle.jvm.version '8' and found incompatible value '9'.
      - Required org.gradle.usage 'java-api' and found value 'java-api-jars'.
  - Variant 'runtimeElements' capability test:producer:unspecified:
      - Provides org.gradle.dependency.bundling 'external'
      - Required org.gradle.jvm.version '8' and found incompatible value '9'.
      - Required org.gradle.usage 'java-api' and found value 'java-runtime-jars'.

通常,这表明您的项目配置错误,并且您的依赖项不兼容。但是,在某些情况下,您可能仍然希望这样做,例如,当模块的子集实际上只需要 Java 9 依赖项,并且不打算在早期版本上使用时。Java 通常不鼓励您这样做(您应该拆分您的模块),但是如果您遇到此问题,您可以通过在消费者端禁用此新行为来解决

java {
   disableAutoTargetJvm()
}

Maven / Ivy 互操作性与依赖项替换中的错误修复

如果您有一个指向 Ivy 依赖项的 Maven 依赖项,其中 default 配置依赖项与 compile + runtime + master 依赖项不匹配并且该 Ivy 依赖项被替换(使用 resolutionStrategy.forceresolutionStrategy.eachDependencyresolutionStrategy.dependencySubstitution),那么此修复程序将影响您。Gradle 5.0 之前的旧版行为仍然存在,而不是被改进的 pom 支持引入的更改所取代。

Gradle 不再忽略 Windows 上 clean 任务、所有 Delete 任务以及存在连接点和符号链接的 project.delete {} 操作的 followSymlink 选项。

发布附加工件的修复

在以前的 Gradle 版本中,除非在发布配置中也添加了项目级别的附加工件作为工件,否则 maven-publishivy-publish 不会发布这些工件。

使用 Gradle 5.3,这些工件现在得到正确考虑并发布。

这意味着在项目发布(Ivy 或 Maven)上都注册的工件将导致发布失败,因为它将创建重复的条目。修复方法是从发布配置中删除这些工件。

从 5.0 及更早版本升级

弃用

请关注 API 链接以了解如何处理这些弃用(如果此处未提供其他信息)

  • org.gradle.plugin.devel.tasks.ValidateTaskPropertiesclassesclasspath 的 Setter(已移除)

  • ConfigurableFileCollection 这样的惰性属性不应该有 setter。请使用 setFrom 代替。例如,

    validateTaskProperties.getClasses().setFrom(fileCollection)
    validateTaskProperties.getClasspath().setFrom(fileCollection)

潜在的破坏性更改

以下更改以前未被弃用

签名 API 更改

Sign 任务的输入和输出文件现在分别通过 Signature.getToSign()Signature.getFile() 跟踪。

集合属性默认为空集合

在 Gradle 5.0 中,使用 ObjectFactory 创建的集合属性实例将没有定义值,需要插件作者显式设置初始值。这证明是笨拙且容易出错的,因此 ObjectFactory 现在返回以空集合作为其初始值的实例。

Worker API:worker 的工作目录不能再设置

由于 JDK 11 不再支持更改正在运行的进程的工作目录,因此现在禁止通过其 fork 选项设置 worker 的工作目录。所有 worker 现在都使用相同的工作目录以实现重用。请传递文件和目录作为参数代替。请参阅 Worker API 文档 中的示例。

本机链接任务的更改

为了扩展我们的惯用 Provider API 实践,org.gradle.nativeplatform.tasks.LinkSharedLibrary 中的 install name 属性受到此更改的影响。

  • getInstallName() 已更改为返回 Property

  • setInstallName(String) 已移除。请使用 Property.set() 代替。

将参数传递给 Windows Resource Compiler

为了扩展我们的惯用 Provider API 实践,WindowsResourceCompile 任务已转换为使用 Provider API。

传递额外的编译器参数现在遵循与 CppCompile 和其他任务相同的模式。

复制的配置不再与原始配置共享 beforeResolve 操作列表

beforeResolve 操作列表不再在复制的配置和原始配置之间共享。相反,复制的配置在进行复制时接收 beforeResolve 操作的副本。在复制后添加的任何 beforeResolve 操作(到任一配置)都不会在原始配置和副本之间共享。这可能会破坏依赖于先前行为的插件。

孵化中的 POM 自定义类型的更改

  • MavenPomDeveloper.properties 的类型已从 Property<Map<String, String>> 更改为 MapProperty<String, String>

  • MavenPomContributor.properties 的类型已从 Property<Map<String, String>> 更改为 MapProperty<String, String>

本机项目的操作系统指定更改

本机组件上孵化中的 operatingSystems 属性已被 targetMachines 属性替换。

归档任务(ZipJarWarEarTar)的更改

扩展 AbstractArchiveTask 的任务的行为更改

AbstractArchiveTask 有几个使用 Provider API 的新属性。扩展这些类型并覆盖基类方法的插件可能不再以相同的方式运行。在内部,AbstractArchiveTask 更喜欢新属性,而像 getArchiveName() 这样的方法是新属性的 facade。

如果您的插件/构建仅使用这些类型(而不扩展它们),则没有任何变化。