本章提供了将旧的 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 版本。我们建议在迁移到 5.0 之前先升级到最新的 4.10.x 版本,以获取最有用的警告和弃用信息。请避免同时升级 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,以获取关于哪些弃用影响您构建的报告。

以下破坏性变更不是由于弃用引起的,而是行为变更的结果

以下破坏性变更将在 Gradle 4.10 中作为弃用警告出现

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

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

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

运行 Gradle 和构建环境
  • 如前所述,Gradle 不再能在 Java 7 上运行。但是,您仍然可以使用 fork 的编译和测试来构建和测试 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) 的配置 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 构建
任务和属性
  • 以下与惰性属性相关的旧类和方法已被移除 — 请使用ObjectFactory.property() 创建 Property 实例

    • PropertyState

    • DirectoryVar

    • RegularFileVar

    • ProjectLayout.newDirectoryVar()

    • ProjectLayout.newFileVar()

    • Project.property(Class)

    • Script.property(Class)

    • ProviderFactory.property(Class)

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

  • 内部的 @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 注解已被移除。

  • ExtensionSchema 中的 isDeferredConfigurable() 方法已被移除。

  • IdeaPlugin.performPostEvaluationActions()EclipsePlugin.performPostEvaluationActions() 已被移除。

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

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

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

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

  • Tooling API 不再能够连接使用低于 Gradle 2.6 版本的构建。通过 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 升级,请忽略此变更。

弃用项

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

不应被替换的内置任务完整列表包括:wrapper, init, help, tasks, projects, buildEnvironment, components, dependencies, dependencyInsight, dependentComponents, model, properties

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

  • HttpBuildCache 不再遵循重定向.

  • Depend 任务类型已被移除。

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

  • ListProperty 不再扩展 Property

从 4.3 及更早版本升级

潜在的破坏性变更

  • AbstractTestTask 现在不仅被 Test 扩展,也被非 JVM 测试任务扩展。因此,插件在配置所有 AbstractTestTask 类型的任务时应小心。

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

  • 已弃用的 InstallExecutable.setDestinationDir(Provider) 已被移除 — 请改用 InstallExecutable.installDirectory

  • 已弃用的 InstallExecutable.setExecutable(Provider) 已被移除 — 请改用 InstallExecutable.executableFile

  • Gradle 将不再优先选择在 PATH 中找到的 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@OutputDirectories 标记的 Iterable 属性中元素的顺序现在变得重要。如果顺序发生变化,该属性将不再被视为最新。

    优先使用带有 @OutputFile/@OutputDirectory 注解的独立属性,或者改用带有 @OutputFiles/@OutputDirectoriesMap 属性。

  • 当存在其他可检查的仓库时,Gradle 将不再忽略来自某个仓库的依赖解析错误。依赖解析将改为失败。这使得解析结果的行为更具确定性。

从 4.1 及更早版本升级

潜在的破坏性变更

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

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

  • FindBugs Plugin 不再显示其分析的进度信息。如果您在任何方面依赖此输出,可以通过设置 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。这可能会影响在使用 --no-daemon 模式时直接在客户端 VM 内运行的构建。我们不鼓励使用 --no-daemon,但如果您必须使用它,可以通过 GRADLE_OPTS 环境变量增加可用内存。

Gradle Daemon 现在以 512MB 堆内存启动,而不是 1GB。大型项目可能需要使用 org.gradle.jvmargs 属性增加此设置。

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

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

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

  • Checkstyle Plugin 现在默认使用 8.12,而不是 6.19。

  • CodeNarc Plugin 现在默认使用 1.2.1,而不是 1.1。

  • JaCoCo Plugin 现在默认使用 0.8.2,而不是 0.8.1。

  • PMD Plugin 现在默认使用 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 Plugin 使用的 BND 库已从 3.4.0 升级到 4.0.0

  • 用于访问 Google Cloud Storage 支持的 Maven/Ivy 仓库的 Google Cloud Storage JSON API Client Library 已从 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 功能预览,尝试约束或 preferreject 以及其他特定版本指示,那么请务必仔细检查您的依赖解析结果。

[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 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 支持的 Artifact 仓库,之前在 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 及更高版本上使用它。

如果设置了 --add-modules java.xml.bind 选项,请从 org.gradle.jvmargs 中移除它。

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

通过这种新行为,如果在 gradlePluginPortal() 仓库中找到的插件或插件的传递依赖没有 Maven POM,则将无法解析。

发布到 Maven 仓库但没有 POM 的 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 Plugin 利用 Java Library Plugin

此外,插件创建的默认分发版将包含 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 不再支持更改运行中进程的工作目录,因此现在禁止通过 Worker 的 Fork 选项设置其工作目录。

所有 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] 考虑尝试使用 Task 创建和配置的延迟 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")

我们建议使用本地仓库进行测试运行,以查看所有 Artifact 是否仍具有预期的坐标。在大多数情况下,一切都应该像以前一样工作,您就完成了。但是,您的 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

这修复了以下安全问题

Gradle 不会公开这些第三方依赖项的 API,但自定义 Gradle 的用户应知晓此信息。