本章提供了将旧版 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 并查看生成的 Build Scan 的弃用视图。如果没有警告,则不会出现“弃用”选项卡。

    Deprecations View of a Gradle Build Scan

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

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

  3. 更新您的插件。

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

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

  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。如果设置了 --add-modules java.xml.bind 选项,您可以将其删除。

潜在的重大更改

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

以下重大更改并非源于弃用,而是行为更改的结果

以下重大更改将在 Gradle 4.10 中显示为弃用警告

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

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

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

运行 Gradle 和构建环境
  • 如前所述,Gradle 不再支持在 Java 7 上运行。但是,您仍然可以使用分叉编译和测试来构建和测试 Java 6 及更高版本的软件。

  • -Dtest.single 命令行选项已移除 — 请改为使用测试筛选

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

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

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

  • 您不能再将 Gradle 构建嵌套在另一个 Gradle 构建的子目录中,除非嵌套构建包含 settings.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 任务属性上使用 @SkipWhenEmpty 注解。

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

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

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

Java 构建
  • CompileOptions.bootClasspath 属性已移除 — 请改为使用 CompileOptions.bootstrapClasspath

  • 您不能再将 -source-path 用作通用编译器参数 — 请改为使用 CompileOptions.sourcepath

  • 您不能再将 -processorpath 用作通用编译器参数 — 请改为使用 CompileOptions.annotationProcessorPath

  • Gradle 不再自动应用编译类路径中的注解处理器 — 请改为使用 CompileOptions.annotationProcessorPath

  • testClassesDir 属性已从 Test 任务中移除 — 请改为使用 testClassesDirs

  • classesDir 属性已从 JDepend 任务和 SourceSetOutput 中移除。请改为使用 JDepend.classesDirsSourceSetOutput.classesDirs 属性。

  • JavaLibrary(PublishArtifact, DependencySet) 构造函数已移除 — 此构造函数由 Shadow 插件使用,因此请确保您将该插件升级到至少 2.x 版本。

  • JavaBasePlugin.configureForSourceSet() 方法已移除。

  • 您不能再创建自己的 JavaPluginConventionApplicationPluginConventionWarPluginConventionEarPluginConventionBasePluginConventionProjectReportsPluginConvention 实例。

  • Maven 插件以前发布高度过时的 Maven 2 元数据格式。现在已更改,它将发布 Maven 3 元数据,就像 Maven Publish 插件一样。

    随着 Maven 2 支持的移除,配置唯一快照行为的方法也已移除。Maven 3 只支持唯一快照,因此我们决定移除它们。

任务和属性
  • 以下与惰性属性相关的遗留类和方法已移除 — 使用 ObjectFactory.property() 创建 Property 实例

    • PropertyState

    • DirectoryVar

    • RegularFileVar

    • ProjectLayout.newDirectoryVar()

    • ProjectLayout.newFileVar()

    • Project.property(Class)

    • Script.property(Class)

    • ProviderFactory.property(Class)

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

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

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

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

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

    • execute()

    • executer

    • getValidators()

    • addValidator()

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

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

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

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

  • SimpleWorkResult 已移除 — 请改为使用 WorkResult.didWork

  • 覆盖在4.8 中已弃用的内置任务现在会产生错误。

    尝试替换内置任务将产生类似于以下的错误

    > 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 任务不再支持此属性。

Kotlin DSL
  • Artifact 配置访问器现在具有 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 上的属性工厂方法有几处更改,可能会影响自定义任务的创建。

从 4.9 及更早版本升级

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

已弃用的类、方法和属性

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

潜在的重大更改

从 4.8 及更早版本升级

潜在的重大更改

从 4.7 及更早版本升级

潜在的重大更改

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

  • TaskContainer.remove() 现在实际删除给定的任务 — 一些插件可能无意中依赖了旧行为。

  • Gradle 现在支持 Maven POM 排除中的隐式通配符.

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

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

  • 错误消息现在将定向到标准错误,而不是标准输出,除非控制台同时连接到标准输出和标准错误。这可能会影响抓取构建的纯控制台输出的工具。如果您从早期版本的 Gradle 升级,请忽略此更改。

弃用

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

不应替换的内置任务完整列表是: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 artifact 而不是 kotlin-stdlib-jre8。这可能会影响您的构建。有关更多详细信息,请参阅Kotlin 文档

从 4.4 及更早版本升级

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

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

潜在的重大更改

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

  • Maven Publish 插件现在生成更完整的 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 版本而不是其他位置。它现在是最后选择。

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

  • 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@OutputDirectoriesIterable 属性中元素的顺序现在很重要。如果顺序发生变化,则该属性不再被视为最新。

    最好使用带有 @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 项目具有项目依赖项的非 Java 项目现在使用 runtimeElements 配置,而不是 default 配置。

    要覆盖此行为,您可以在项目依赖项中显式声明要使用的配置。例如: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] 代码质量插件的新默认版本

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

[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) 文件,这些文件实际上是使用 <dependencyManagement> 部分来控制直接和传递依赖项版本的 POM 文件。您只需将 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 库插件都遵循编译和运行时作用域的分离。这意味着编译类路径仅包含编译作用域的依赖项,而运行时类路径也添加了运行时作用域的依赖项。如果您使用 Gradle 开发和发布 Java 库,其中 apiimplementation 依赖项之间的分离反映在已发布的作用域中,则此功能特别有用。

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

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

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

输入和输出不会自动注册

这些方法返回的 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 支持的 artifact 仓库,您以前在 Java 9 及更高版本上运行时必须向 org.gradle.jvmargs 添加 --add-modules java.xml.bind

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

如果设置了 --add-modules java.xml.bind 选项,请将其删除。

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

使用此新行为,如果在 gradlePluginPortal() 仓库中找到的插件或插件的传递依赖项没有 Maven POM,则它将无法解析。

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

如果您受困于糟糕的插件,可以通过为 gradlePluginPortal() 仓库重新启用 JAR 作为元数据源来解决

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 插件利用 Java Library 插件

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

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

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

使用现有 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 将 artifact 发布到 AWS S3 存储桶。从这个版本开始,上传到 S3 存储桶的每个 artifact 都将配备 bucket-owner-full-control 预定义 ACL。请确保用于发布 artifact 的 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 插件

现在发布插件已经稳定,我们建议您从传统发布机制迁移到标准 Java 项目,即基于Java 插件的项目。这包括使用以下任何一个插件的项目:Java 库插件应用程序插件War 插件

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

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

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

新的稳定行为可以通过将以下内容添加到您的设置文件中来启用

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

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

例如,在新行为下,以下逻辑假设 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

这修复了以下安全问题

Gradle 不公开这些第三方依赖项的公共 API,但那些自定义 Gradle 的人会希望了解。