本章提供将旧版本 Gradle 4.x 构建迁移到 Gradle 5.0 所需的信息。在大多数情况下,您需要应用从您要升级的版本之后的所有版本的更改。例如,如果您要从 Gradle 4.3 升级到 5.0,您还需要应用自 4.4、4.5 等直到 5.0 的更改。

如果您正在将 Gradle 用于 Android,则需要迁移到 Android Gradle 插件和 Android Studio 的 3.3 或更高版本。

面向所有用户

  1. 如果您尚未升级到最新的 4.10.x 版本,请阅读下面的 章节,以获取将项目升级到最新的 4.10.x 版本的帮助。我们建议升级到最新的 4.10.x 版本,以便在迁移到 5.0 之前获得最有用的警告和弃用信息。为了便于在出现潜在问题时进行故障排除,请避免同时升级 Gradle 和迁移到 Kotlin DSL。

  2. 尝试运行 gradle help --scan 并查看生成的构建扫描的 弃用视图。如果没有警告,则不会显示“弃用”选项卡。

    Deprecations View of a Gradle Build Scan

    这样做是为了让您可以看到适用于您构建的任何弃用警告。如果您尝试直接升级到 Gradle 5.x,它将生成(可能不太明显的)错误。

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

  3. 更新您的插件。

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

    特别是,您需要使用至少 2.x 版本的 Shadow Plugin

  4. 运行 gradle wrapper --gradle-version 5.0 以将项目更新到 5.0

  5. 如果您尚未迁移到 Java 8 或更高版本,请进行迁移。Gradle 4.x 需要 Java 7,而 Gradle 5 需要 Java 8 才能运行。

  6. 阅读 从 4.10 升级 章节并进行任何必要的更改。

  7. 尝试运行项目并使用 问题排查指南 调试任何错误。

此外,Gradle 还添加了几个重要的新功能和改进功能,您应该考虑在构建中使用这些功能

需要注意的其他可能破坏构建的显著更改包括

从 4.10 及更早版本升级

如果您尚未升级到 4.10 版本,请跳至适用于您当前 Gradle 版本的章节,然后逐步升级到此处。然后,在从 Gradle 4.10 迁移到 5.0 时应用这些更改。

其他更改

  • 不再需要 enableFeaturePreview('IMPROVED_POM_SUPPORT')enableFeaturePreview('STABLE_PUBLISHING') 标志。这些功能现在默认启用。

  • Gradle 现在为 Java 9 及更高版本捆绑了 JAXB。如果已设置,您可以从 org.gradle.jvmargs 中删除 --add-modules java.xml.bind 选项。

潜在的破坏性更改

本节中的更改可能会破坏您的构建,但绝大多数更改已被弃用很长时间,并且很少有构建会受到其中大量更改的影响。我们强烈建议首先升级到 Gradle 4.10,以获取有关哪些弃用会影响您的构建的报告。

以下破坏性更改并非来自弃用,而是行为更改的结果

  • 使用 POM 时,编译和运行时依赖项分离

  • publishing {} 块的评估不再延迟到需要时,而是像任何其他块一样运行。如果您需要延迟评估,请使用 afterEvaluate {}

  • JavadocGroovydoc task 现在在执行前删除文档的目标目录。添加此功能是为了删除上次 task 执行中的过时输出文件。

  • Java Library Distribution Plugin 现在基于 Java Library Plugin 而不是 Java Plugin

    虽然它应用了 Java Plugin,但其行为略有不同(例如,它添加了 api 配置)。因此,请确保检查升级后您的构建是否按预期运行。

  • CheckstyleReportFindBugsReport 上的 html 属性现在返回 CustomizableHtmlReport 实例,该实例更易于从 Java 和 Kotlin 等静态类型语言进行配置。

  • 配置避免 API 已更新,以防止创建和配置从未使用过的 task。

  • 命令行客户端、Gradle 守护程序和所有工作进程(包括编译器和测试执行器)的 默认内存设置 已大大减少。

  • 几个代码质量插件的 默认版本 已更新。

  • Gradle 使用的几个 库版本 已升级。

以下破坏性更改将作为 Gradle 4.10 的弃用警告出现

常规
  • << 用于 task 定义不再有效。换句话说,您不能使用语法 task myTask << { …​ }

    请改用 Task.doLast() 方法,如下所示

    task myTask {
        doLast {
            ...
        }
    }
  • 您不能再在域对象名称(例如项目和 task 名称)中使用以下任何字符:<空格> / \ : < > " ? * | 。您也不应使用 . 作为前导或尾随字符。

运行 Gradle 和构建环境
  • 如前所述,Gradle 无法再在 Java 7 上运行。但是,您仍然可以使用 forked compilation and testing 来构建和测试适用于 Java 6 及更高版本的软件。

  • -Dtest.single 命令行选项已删除 — 请改用 测试过滤

  • -Dtest.debug 命令行选项已删除 — 请改用 --debug-jvm 选项

  • -u/--no-search-upward 命令行选项已删除 — 请确保您的所有构建都有 settings.gradle 文件。

  • --recompile-scripts 命令行选项已删除。

  • 除非嵌套的构建具有 settings.gradle 文件,否则您不能再在另一个 Gradle 构建的子目录中嵌套 Gradle 构建。

  • DirectoryBuildCache.setTargetSizeInMB(long) 方法已删除 — 请改用 DirectoryBuildCache.removeUnusedEntriesAfterDays

  • org.gradle.readLoggingConfigFile 系统属性不再执行任何操作 — 请更新受影响的测试以使用您的 java.util.logging 设置。

处理文件
  • 您不能再使用 as 关键字或 asType() 方法将 FileCollection 对象强制转换为其他类型。

  • 您不能再将 null 作为 CopySpec.from(Object, Action) 的配置操作传递。

  • 为了更好地与 Kotlin DSL 兼容,CopySpec.duplicatesStrategy 不再可为空。属性 setter 不再接受 null 作为将属性重置回其默认值的方式。请改用 DuplicatesStrategy.INHERIT

  • FileCollection.stopExecutionIfEmpty() 方法已删除 — 请改用 FileCollection task 属性上的 @SkipWhenEmpty 注解。

  • FileCollection.add() 方法已删除 — 请使用 Project.files()Project.fileTree() 创建可配置的文件集合/文件树,并通过 ConfigurableFileCollection.from() 将其添加到其中。

  • SimpleFileCollection 已删除 — 请改用 Project.files(Object…​)

  • 不要让您自己的类扩展 AbstractFileCollection — 请改用 Project.files() 方法。此问题可能会表现为缺少 getBuildDependencies() 方法。

Java 构建
Task 和属性
  • 以下与 延迟属性 相关的旧类和方法已删除 — 请使用 ObjectFactory.property() 创建 Property 实例

    • PropertyState

    • DirectoryVar

    • RegularFileVar

    • ProjectLayout.newDirectoryVar()

    • ProjectLayout.newFileVar()

    • Project.property(Class)

    • Script.property(Class)

    • ProviderFactory.property(Class)

  • 使用 task 配置避免 API 配置和注册的 Task 对可以从配置操作调用的其他方法有更多限制。

  • 内部 @Option@OptionValues 注解 — 包 org.gradle.api.internal.tasks.options — 已删除。请改用公共 @Option@OptionValues 注解。

  • Task.deleteAllActions() 方法已删除,没有替代方法。

  • Task.dependsOnTaskDidWork() 方法已删除 — 请改用 声明的输入和输出

  • 以下 TaskInternal 的属性和方法已删除 — 请使用 task 依赖项、task 规则、可重用的实用程序方法或 Worker API 来代替直接执行 task。

    • execute()

    • executer

    • getValidators()

    • addValidator()

  • TaskInputs.file(Object) 方法不能再使用解析为单个常规文件以外的任何内容的参数调用。

  • TaskInputs.dir(Object) 方法不能再使用解析为单个目录以外的任何内容的参数调用。

  • 您不能再通过 TaskInputsTaskOutputs 注册无效的输入和输出。

  • TaskDestroyables.file()TaskDestroyables.files() 方法已删除 — 请改用 TaskDestroyables.register()

  • SimpleWorkResult 已删除 — 请使用 WorkResult.didWork

  • 覆盖 4.8 中弃用 的内置 task 现在会生成错误。

    尝试替换内置 task 将生成类似于以下的错误

    > Cannot add task 'wrapper' as a task with that name already exists.
Scala 和 Play
  • 不再支持 Play 2.2 — 请升级您正在使用的 Play 版本。

  • ScalaDocOptions.styleSheet 属性已删除 — Scala 2.11.8 及更高版本中的 Scaladoc Ant task 不再支持此属性。

Kotlin DSL
  • 工件配置访问器现在具有 NamedDomainObjectProvider<Configuration> 类型,而不是 Configuration

  • PluginAware.apply<T>(to) 已重命名为 PluginAware.applyTo<T>(target)

这两个更改都可能导致脚本编译错误。有关更多信息以及如何修复因上述更改而损坏的构建,请参阅 Gradle Kotlin DSL 发行说明

其他
  • ConfigurableReport.setDestination(Object) 方法已删除 — 请改用 ConfigurableReport.setDestination(File)

  • Signature.setFile(File) 方法已删除 — Gradle 不支持更改生成的签名的输出文件。

  • 只读 Signature.toSignArtifact 属性已删除 — 它永远不应成为公共 API 的一部分。

  • @DeferredConfigurable 注解已删除。

  • 方法 isDeferredConfigurable() 已从 ExtensionSchema 中删除。

  • IdeaPlugin.performPostEvaluationActions()EclipsePlugin.performPostEvaluationActions() 已删除。

  • 方法 BroadcastingCollectionEventRegister.getAddAction() 已删除,没有替代方法。

  • 内部 org.gradle.util 包不再默认导入。

    理想情况下,您不应使用此包中的类,但作为快速修复,您可以为这些类向构建脚本添加显式导入。

  • gradlePluginPortal() 仓库 默认情况下不再查找没有 POM 的 JAR

  • Tooling API 无法再连接到使用低于 Gradle 2.6 的 Gradle 版本的构建。通过 TestKit 运行的构建也适用。

  • Gradle 5.0 需要最低 Tooling API 客户端版本 3.0。旧版本的客户端库无法再使用 Gradle 5.0 运行构建。

  • IdeaModule Tooling API 模型元素包含检索资源和测试资源的方法,因此这些元素已从 IdeaModule.getSourceDirs()IdeaModule.getTestSourceDirs() 的结果中删除。

  • 在以前的 Gradle 版本中,子类可以访问 SourceTask 中的 source 字段。现在情况并非如此,因为 source 字段现在声明为 private

  • 在 Worker API 中,worker 的工作目录不能再设置

  • 依赖项和版本约束 相关的行为更改可能会影响少数用户。

  • DefaultTask 上的属性工厂方法 发生了一些更改,可能会影响自定义 task 的创建。

从 4.9 及更早版本升级

如果您尚未升级到 4.9 版本,请跳至适用于您当前 Gradle 版本的章节,然后逐步升级到此处。然后,在升级到 Gradle 4.10 时应用这些更改。

已弃用的类、方法和属性

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

潜在的破坏性更改

从 4.8 及更早版本升级

潜在的破坏性更改

从 4.7 及更早版本升级

潜在的破坏性更改

  • 如果找不到指定的 init 脚本,构建现在将失败。

  • TaskContainer.remove() 现在实际上删除了给定的 task — 某些插件可能意外地依赖了旧的行为。

  • Gradle 现在遵循 Maven POM 排除项中的隐式通配符.

  • Kotlin DSL 现在遵循 JSR-305 包注解。

    这将导致一些根据 JSR-305 注解的类型被视为可为空,而之前它们被视为不可为空。这可能会导致构建脚本中出现编译错误。有关详细信息,请参阅 相关的 Kotlin DSL 发行说明

  • 除非控制台同时连接到标准输出和标准错误,否则错误消息现在将定向到标准错误而不是标准输出。如果您是从早期版本的 Gradle 升级,请忽略此更改。

弃用

在此版本之前,允许构建替换内置 task。此功能已被弃用

以下是不应被替换的内置任务的完整列表:wrapperinithelptasksprojectsbuildEnvironmentcomponentsdependenciesdependencyInsightdependentComponentsmodelproperties

从 4.6 及更早版本升级

潜在的破坏性变更

  • Gradle 现在将按照惯例,在根项目的 config/checkstyle 目录中查找 Checkstyle 配置文件。

    子项目中的 Checkstyle 配置文件(旧的默认位置)将被忽略,除非您通过 checkstyle.configDircheckstyle.config 显式配置其路径。

  • Gradle 的 纯文本控制台输出 的结构已更改,这可能会破坏抓取该输出的工具。

  • 许多与编译、链接和安装相关的原生任务的 API 已发生重大更改

  • [Kotlin DSL] 用于访问 Gradle 构建属性(例如在 gradle.properties 中定义的属性)的委托属性现在必须显式类型化。

  • [Kotlin DSL] 在嵌套作用域内声明 plugins {} 代码块现在会抛出异常。

  • [Kotlin DSL] 现在只允许一个 pluginManagement {} 代码块。

  • org.gradle.api.artifacts.cache.* 接口提供的缓存控制 DSL 不再可用。

  • getEnabledDirectoryReportDestinations()getEnabledFileReportDestinations()getEnabledReportNames() 已全部从 org.gradle.api.reporting.ReportContainer 中移除。

  • StartParameter.projectPropertiesStartParameter.systemPropertiesArgs 现在返回不可变映射。

从 4.5 及更早版本升级

弃用

  • 您不应将注解处理器放在编译类路径上,也不应使用 -processorpath 编译器参数声明它们。

    应将它们添加到 annotationProcessor 配置中。如果您不想要任何处理,但您的编译类路径意外地包含了一个处理器(例如,作为您依赖的库的一部分),请使用 -proc:none 编译器参数来忽略它。

  • 使用 CommandLineArgumentProvider 代替 CompilerArgumentProvider

潜在的破坏性变更

  • Java 插件现在为每个源集添加一个 sourceSetAnnotationProcessor 配置,如果其中任何一个与您现有的配置匹配,则可能会中断。我们建议您删除冲突的配置声明。

  • StartParameter.taskOutputCacheEnabled 属性已被 StartParameter.setBuildCacheEnabled(boolean) 替换。

  • Visual Studio 集成现在仅 为构建中的所有组件配置单个解决方案

  • Gradle 已将 HttpClient 从 4.4.1 替换为 4.5.5 版本。

  • Gradle 现在捆绑了 kotlin-stdlib-jdk8 工件,而不是 kotlin-stdlib-jre8。这可能会影响您的构建。请参阅 Kotlin 文档 以获取更多详细信息。

从 4.4 及更早版本升级

  • 确保您有一个 settings.gradle 文件:它可以避免性能损失,并允许您设置根项目的名称。

  • Gradle 现在忽略包含构建(组合构建)的构建缓存配置,而是对所有构建使用根构建的配置。

潜在的破坏性变更

  • 移除了两个重载的 ValidateTaskProperties.setOutputFile() 方法。当从构建脚本访问任务时,它们会被自动生成的 setter 替换,但从插件和构建脚本之外的其他代码访问则不会。

  • Maven Publish Plugin 现在生成更完整的 maven-metadata.xml 文件,包括维护 <snapshotVersion> 元素的列表。某些旧版本的 Maven 可能无法使用此元数据。

  • HttpBuildCache 不再遵循重定向.

  • Depend 任务类型已被移除。

  • Project.file(Object) 不再规范化不区分大小写的文件系统上的文件路径的大小写。现在,在这种情况下,它会忽略大小写,并且不会触及文件系统。

  • ListProperty 不再扩展 Property

从 4.3 及更早版本升级

潜在的破坏性变更

  • AbstractTestTask 现在由非 JVM 测试任务以及 Test 扩展。插件应注意配置所有 AbstractTestTask 类型的任务,因为这种情况。

  • EclipseClasspath.defaultOutputDir 的默认输出位置已从 $projectDir/bin 更改为 $projectDir/bin/default

  • 已移除弃用的 InstallExecutable.setDestinationDir(Provider) — 使用 InstallExecutable.installDirectory 代替。

  • 已移除弃用的 InstallExecutable.setExecutable(Provider) — 使用 InstallExecutable.executableFile 代替。

  • Gradle 将不再优先选择在路径上找到的 Visual Studio 版本,而不是其他位置。现在它是最后的选择。

    您可以通过指定您想要的 Visual Studio 版本的安装目录来绕过工具链发现,通过 VisualCpp.setInstallDir(Object)

  • pluginManagement.repositories 现在是 RepositoryHandler 类型,而不是已移除的 PluginRepositoriesSpec

  • 依赖项解析期间的 5xx HTTP 错误现在将在构建中触发异常。

  • 嵌入式 Apache Ant 已从 1.9.6 升级到 1.9.9。

  • Gradle 使用的几个第三方库已升级,以修复安全问题。

从 4.2 及更早版本升级

其他弃用

潜在的破坏性变更

  • DefaultTask.newOutputDirectory() 现在返回 DirectoryProperty 而不是 DirectoryVar

  • DefaultTask.newOutputFile() 现在返回 RegularFileProperty 而不是 RegularFileVar

  • DefaultTask.newInputFile() 现在返回 RegularFileProperty 而不是 RegularFileVar

  • ProjectLayout.buildDirectory 现在返回 DirectoryProperty 而不是 DirectoryVar

  • AbstractNativeCompileTask.compilerArgs 现在是 ListProperty<String> 类型,而不是 List<String>

  • AbstractNativeCompileTask.objectFileDir 现在是 DirectoryProperty 类型,而不是 File

  • AbstractLinkTask.linkerArgs 现在是 ListProperty<String> 类型,而不是 List<String>

  • TaskDestroyables.getFiles() 不再是公共 API 的一部分。

  • 依赖项的重叠版本范围现在会导致 Gradle 选择满足所有声明范围的版本。

    例如,如果找到对 some-module 的依赖项,其版本范围为 [3,6],并且也传递性地找到版本范围为 [4,8] 的依赖项,则 Gradle 现在选择版本 6 而不是 8。之前的行为是选择 8。

  • 使用 @OutputFiles@OutputDirectories 注解标记的 Iterable 属性中元素的顺序现在很重要。如果顺序更改,则该属性不再被视为最新。

    首选使用带有 @OutputFile/@OutputDirectory 注解的单独属性,或使用带有 @OutputFiles/@OutputDirectoriesMap 属性代替。

  • 当存在另一个可以检查的仓库时,Gradle 将不再忽略来自仓库的依赖项解析错误。而是依赖项解析将失败。这导致关于解析结果的更确定性行为。

从 4.1 及更早版本升级

潜在的破坏性变更

  • TaskFilePropertyBuilderTaskOutputFilePropertyBuilder 上的 withPathSensitivity() 方法已被移除。

  • 捆绑的 bndlib 已从 3.2.0 升级到 3.4.0。

  • FindBugs 插件不再呈现其分析的进度信息。如果您以任何方式依赖该输出,您可以使用 FindBugs.showProgress 启用它。

从 4.0 升级

  • 考虑使用新的 Worker API 以便在您的构建中启用并行运行的工作单元。

已弃用的类、方法和属性

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

潜在的破坏性变更

  • 非 Java 项目现在默认使用 runtimeElements 配置,而不是 default 配置,如果它们对 Java 项目有项目依赖

    要覆盖此行为,您可以显式声明要在项目依赖中使用的配置。例如:project(path: ':myJavaProject', configuration: 'default')

  • 默认 Zinc 编译器从 0.3.13 升级到 0.3.15。

  • [Kotlin DSL] 基础包已从 org.gradle.script.lang.kotlin 重命名为 org.gradle.kotlin.dsl

详细变更

[5.0] 默认内存设置已更改

命令行客户端现在以 64MB 的堆内存启动,而不是 1GB。这可能会影响直接在客户端 VM 中使用 --no-daemon 模式运行的构建。我们不鼓励使用 --no-daemon,但如果您必须使用它,您可以使用 GRADLE_OPTS 环境变量增加可用内存。

Gradle 守护进程现在以 512MB 的堆内存启动,而不是 1GB。大型项目可能必须使用 org.gradle.jvmargs 属性增加此设置。

所有 worker,包括编译器和测试执行器,现在都以 512MB 的堆内存启动。之前的默认值是物理内存的 1/4。大型项目可能必须在相关任务上增加此设置,例如 JavaCompileTest

[5.0] 代码质量插件的新默认工具版本

以下代码质量插件的默认工具版本已更新

  • Checkstyle 插件 现在默认使用 8.12 而不是 6.19。

  • CodeNarc 插件 现在默认使用 1.2.1 而不是 1.1。

  • JaCoCo 插件 现在默认使用 0.8.2 而不是 0.8.1。

  • PMD 插件 现在默认使用 6.8.0 而不是 5.6.1。

    此外,默认规则集已从现在已弃用的 java-basic 更改为 category/java/errorprone.xml

    我们建议显式配置规则集。

[5.0] 库升级

Gradle 使用的几个库已升级

  • Groovy 已从 2.4.15 升级到 2.5.4

  • Ant 已从 1.9.11 升级到 1.9.13

  • 用于访问 S3 支持的 Maven/Ivy 仓库的 AWS SDK 已从 1.11.267 升级到 1.11.407

  • OSGi 插件使用的 BND 库已从 3.4.0 升级到 4.0.0

  • 用于访问 Google Cloud Storage 支持的 Maven/Ivy 仓库的 Google Cloud Storage JSON API 客户端库已从 v1-rev116-1.23.0 升级到 v1-rev136-1.25.0。

  • Ivy 已从 2.2.0 升级到 2.3.0

  • Test 任务使用的 JUnit Platform 库已从 1.0.3 升级到 1.3.1。

  • 用于访问 Maven 仓库的 Maven Wagon 库已从 2.4 升级到 3.0.0。

  • SLF4J 已从 1.7.16 升级到 1.7.25

[5.0] 改进了对依赖项和版本约束的支持

在 Gradle 4.x 发布流中,为依赖项解析引擎添加了新的 @Incubating 功能。这些功能包括复杂的版本约束(preferstrictlyreject)、依赖项约束和 platform 依赖项。

如果您一直在使用 IMPROVED_POM_SUPPORT 功能预览,尝试约束或 prefer、reject 和其他特定版本指示,请务必仔细查看您的依赖项解析结果。

[5.0] BOM 导入

Gradle 现在提供对导入物料清单 (BOM) 文件的支持,这些文件实际上是 POM 文件,使用 <dependencyManagement> 部分来控制直接和传递依赖项的版本。您只需将 POM 声明为 platform 依赖项即可。

以下示例从声明的 Spring Boot BOM 中选择 gsondom4j 依赖项的版本

dependencies {
    // import a BOM
    implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')

    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'
}

[5.0] 使用 POM 时编译和运行时依赖项的分离

自 Gradle 1.0 以来,运行时作用域的依赖项已包含在 Java 编译类路径中,这有一些缺点

  • 编译类路径比需要的要大得多,减慢了编译速度。

  • 编译类路径包含不影响编译的运行时作用域文件,当这些文件更改时会导致不必要的重新编译。

通过这种新行为,Java 和 Java Library 插件都遵循 编译和运行时作用域的分离。这意味着编译类路径仅包含编译作用域的依赖项,而运行时类路径也添加了运行时作用域的依赖项。如果您使用 Gradle 开发和发布 Java 库,其中 apiimplementation 依赖项之间的分离反映在已发布的作用域中,则这尤其有用。

[5.0] DefaultTask 上属性工厂方法的更改

DefaultTask 上的属性工厂方法现在是 final 的

属性工厂方法(如 newInputFile())旨在从扩展 DefaultTask 的类型的构造函数中调用。这些方法现在是 final 的,以避免子类覆盖这些方法并使用未初始化的状态。

输入和输出不再自动注册

这些方法返回的 Property 实例不再自动注册为任务的输入或输出。Property 实例需要在通常的方式中声明为输入或输出,例如附加 @OutputFile 等注解或使用运行时 API 注册属性。

例如,您以前可以使用以下语法,并将两个 outputFile 实例都注册为声明的输出

build.gradle
class MyTask extends DefaultTask {
    // note: no annotation here
    final RegularFileProperty outputFile = newOutputFile()
}

task myOtherTask {
    def outputFile = newOutputFile()
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    // note: no annotation here
    val outputFile: RegularFileProperty = newOutputFile()
}

task("myOtherTask") {
    val outputFile = newOutputFile()
    doLast { ... }
}

现在您必须显式注册 outputFile,像这样

build.gradle
class MyTask extends DefaultTask {
    @OutputFile // property needs an annotation
    final RegularFileProperty outputFile = project.objects.fileProperty()
}

task myOtherTask {
    def outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    @OutputFile // property needs an annotation
    val outputFile: RegularFileProperty = project.objects.fileProperty()
}

task("myOtherTask") {
    val outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}

[5.0] Gradle 现在为 Java 9 及更高版本捆绑 JAXB

为了使用 S3 支持的工件仓库,您以前必须在 Java 9 及更高版本上运行时将 --add-modules java.xml.bind 添加到 org.gradle.jvmargs

由于 Java 11 不再包含 java.xml.bind 模块,Gradle 现在捆绑了 JAXB 2.3.1 (com.sun.xml.bind:jaxb-impl) 并在 Java 9 及更高版本上使用它。

请从 org.gradle.jvmargs 中删除 --add-modules java.xml.bind 选项(如果已设置)。

[5.0] gradlePluginPortal() 仓库默认不再查找没有 POM 的 JAR

使用这种新行为,如果 gradlePluginPortal() 仓库中找到的插件或插件的传递依赖项没有 Maven POM,则解析将失败。

发布到没有 POM 的 Maven 仓库的工件应该修复。如果您遇到此类工件,请要求插件或库作者发布带有正确元数据的新版本。

如果您被不良插件困扰,您可以通过重新启用 JAR 作为 gradlePluginPortal() 仓库的元数据源来解决

settings.gradle
pluginManagement {
    repositories {
        gradlePluginPortal().tap {
            metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}
settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal().apply {
            (this as MavenArtifactRepository).metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}

Java Library Distribution Plugin 利用 Java Library Plugin

此外,插件创建的默认分发将包含 runtimeClasspath 配置的所有工件,而不是已弃用的 runtime 配置。

配置避免 API 禁止常见的配置错误

配置避免 API 在 Gradle 4.9 中引入,允许您避免创建和配置从未使用过的任务。

使用现有的 API,此示例添加了两个任务(foobar

build.gradle
tasks.create("foo") {
    tasks.create("bar")
}
build.gradle.kts
tasks.create("foo") {
    tasks.create("bar")
}

当将其转换为使用新的 API 时,会发生一些令人惊讶的事情:bar 不存在。新的 API 仅在必要时执行配置操作,因此任务 barregister() 仅在配置 foo 时执行。

build.gradle
tasks.register("foo") {
    tasks.register("bar") // WRONG
}
build.gradle.kts
tasks.register("foo") {
    tasks.register("bar") // WRONG
}

为避免这种情况,Gradle 现在检测到这一点,并在使用新 API 时阻止修改底层容器(通过 create()register())。

[5.0] Worker API:worker 的工作目录不再可以设置

由于 JDK 11 不再支持更改正在运行的进程的工作目录,因此现在禁止通过其 fork 选项设置 worker 的工作目录。

所有 worker 现在都使用相同的工作目录以启用重用。

请将文件和目录作为参数传递。

[4.10] 发布到 AWS S3 需要新的权限

S3 仓库传输协议允许 Gradle 将工件发布到 AWS S3 存储桶。从此版本开始,上传到 S3 存储桶的每个工件都将配备 bucket-owner-full-control 预置 ACL。确保用于发布工件的 AWS 帐户具有 s3:PutObjectAcls3:PutObjectVersionAcl 权限,否则上传将失败。

{
    "Version":"2012-10-17",
    "Statement":[
        // ...
        {
            "Effect":"Allow",
            "Action":[
                "s3:PutObject", // necessary for uploading objects
                "s3:PutObjectAcl", // required starting with this release
                "s3:PutObjectVersionAcl" // if S3 bucket versioning is enabled
            ],
            "Resource":"arn:aws:s3:::myCompanyBucket/*"
        }
    ]
}

有关更多信息,请参阅 AWS S3 跨账户访问

[4.9] 考虑尝试用于任务创建和配置的惰性 API

Gradle 4.9 引入了一种新的延迟创建和配置任务的方式。当您对配置成本高昂的任务或当您有许多任务时使用此方法,如果这些任务不运行,您的构建配置时间可以显着减少。

您可以在 任务配置避免 章节中了解有关延迟创建任务的更多信息。您还可以在 这篇博客文章 中阅读有关此新功能的背景信息。

[4.8] 切换到 Maven Publish 和 Ivy Publish Plugins

既然发布插件是稳定的,我们建议您从标准 Java 项目(即基于 Java Plugin 的项目)的旧版发布机制迁移。这包括使用以下任何一个的项目:Java Library PluginApplication PluginWar Plugin

要使用新方法,只需将任何 upload<Conf> 配置替换为 publishing {} 代码块。有关更多信息,请参阅 发布概述章节

[4.8] 对发布插件使用延迟配置

在 Gradle 4.8 之前,publishing {} 代码块被隐式地视为好像其中的所有逻辑都在项目评估后执行。这令人困惑,因为它是唯一以这种方式运行的代码块。作为 Gradle 4.8 中稳定化工作的一部分,我们正在弃用此行为,并要求所有用户迁移他们的构建。

可以通过将以下内容添加到您的 settings 文件来开启新的稳定行为

settings.gradle
enableFeaturePreview('STABLE_PUBLISHING')
settings.gradle.kts
enableFeaturePreview("STABLE_PUBLISHING")

我们建议使用本地仓库进行测试运行,以查看所有工件是否仍具有预期的坐标。在大多数情况下,一切都应该像以前一样工作,您就完成了。但是,您的发布代码块可能依赖于隐式延迟配置,特别是如果它依赖于在构建的配置阶段可能更改的值。

例如,在新行为下,以下逻辑假定 jar.archiveBaseName 在设置 artifactId 后不会更改

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                artifactId = jar.archiveBaseName
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                artifactId = tasks.jar.get().archiveBaseName.get()
            }
        }
    }
}

如果该假设不正确或将来可能不正确,则必须在 afterEvaluate {} 代码块中设置 artifactId,如下所示

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                afterEvaluate {
                    artifactId = jar.archiveBaseName
                }
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                afterEvaluate {
                    artifactId = tasks.jar.get().archiveBbaseName.get()
                }
            }
        }
    }
}

[4.8] 配置现有的 wrapperinit 任务

您不应再定义自己的 wrapperinit 任务。而是配置现有任务,例如通过将此

build.gradle
task wrapper(type: Wrapper) {
    ...
}
build.gradle.kts
task<Wrapper>("wrapper") {
    ...
}

转换为此

build.gradle
wrapper {
    ...
}
build.gradle.kts
tasks.wrapper {
    ...
}

[4.8] Gradle 现在遵循 Maven POM 排除中的隐式通配符

如果 Maven POM 中的排除缺少 groupIdartifactId,Gradle 过去会忽略该排除。现在,缺少的元素被视为隐式通配符——例如 <groupId>*</groupId> ——这意味着您的某些依赖项现在可能被排除在以前没有排除的地方。

您将需要显式声明您需要的任何缺少的依赖项。

[4.7] Gradle 的纯文本控制台输出的结构更改

纯文本控制台模式现在以与富文本控制台一致的方式格式化输出,这意味着输出格式已更改。例如

  • 给定任务产生的输出现在组合在一起,即使其他任务与其并行执行。

  • 任务执行标头以 "> Task" 前缀打印。

  • 在构建执行期间产生的所有输出都写入标准输出文件句柄。这包括写入 System.err 的消息,除非您将标准错误重定向到文件或任何其他非控制台目标。

这可能会破坏从纯文本控制台输出中抓取详细信息的工具。

[4.6] 与编译、链接和安装相关的原生任务的 API 更改

许多与编译、链接和安装原生库和应用程序相关的任务已转换为 Provider API,以便它们支持 惰性配置。此转换对任务的 API 引入了一些破坏性更改,以便它们符合 Provider API 的约定。

以下任务已更改

AbstractLinkTask 及其子类
  • getDestinationDir() 已替换为 getDestinationDirectory()

  • getBinaryFile()getOutputFile() 已替换为 getLinkedFile()

  • setOutputFile(File) 已移除。请使用 Property.set() 代替。

  • setOutputFile(Provider) 已移除。请使用 Property.set() 代替。

  • getTargetPlatform() 已更改为返回 Property

  • setTargetPlatform(NativePlatform) 已移除。请使用 Property.set() 代替。

  • getToolChain() 已更改为返回 Property

  • setToolChain(NativeToolChain) 已移除。请使用 Property.set() 代替。

CreateStaticLibrary
  • getOutputFile() 已更改为返回 Property

  • setOutputFile(File) 已移除。请使用 Property.set() 代替。

  • setOutputFile(Provider) 已移除。请使用 Property.set() 代替。

  • getTargetPlatform() 已更改为返回 Property

  • setTargetPlatform(NativePlatform) 已移除。请使用 Property.set() 代替。

  • getToolChain() 已更改为返回 Property

  • setToolChain(NativeToolChain) 已移除。请使用 Property.set() 代替。

  • getStaticLibArgs() 已更改为返回 ListProperty

  • setStaticLibArgs(List) 已移除。请使用 ListProperty.set() 代替。

InstallExecutable
  • getSourceFile() 已替换为 getExecutableFile()

  • getPlatform() 已替换为 getTargetPlatform()

  • setTargetPlatform(NativePlatform) 已移除。请使用 Property.set() 代替。

  • getToolChain() 已更改为返回 Property

  • setToolChain(NativeToolChain) 已移除。请使用 Property.set() 代替。

以下任务也看到了类似的更改

[4.6] Visual Studio 集成仅支持构建的所有组件的单个解决方案文件

VisualStudioExtension 不再具有 solutions 属性。相反,您可以在根项目中通过 VisualStudioRootExtension 配置单个解决方案,如下所示

build.gradle
model {
    visualStudio {
        solution {
            solutionFile.location = "vs/${name}.sln"
        }
    }
}

此外,不再有为每个组件生成解决方案文件的单个任务,而是一个 visualStudio 任务,它生成一个包含构建中所有组件的解决方案文件。

[4.5] HttpBuildCache 不再遵循重定向

当通过 HttpBuildCache 连接到 HTTP 构建缓存后端时,Gradle 不再遵循重定向,而是将其视为错误。从构建缓存后端获取重定向主要是配置错误——例如,使用 "http" URL 而不是 "https"——并且对性能有负面影响。

[4.4] 第三方依赖项升级

此版本包括几个第三方依赖项的升级

  • jackson: 2.6.6 → 2.8.9

  • plexus-utils: 2.0.6 → 2.1

  • xercesImpl: 2.9.1 → 2.11.0

  • bsh: 2.0b4 → 2.0b6

  • bouncycastle: 1.57 → 1.58

这修复了以下安全问题

  • CVE-2017-7525(严重)

  • SONATYPE-2017-0359(严重)

  • SONATYPE-2017-0355(严重)

  • SONATYPE-2017-0398(严重)

  • CVE-2013-4002(严重)

  • CVE-2016-2510(严重)

  • SONATYPE-2016-0397(严重)

  • CVE-2009-2625(严重)

  • SONATYPE-2017-0348(严重)

Gradle 不会为这些第三方依赖项公开公共 API,但那些自定义 Gradle 的用户会希望知道这一点。