本章提供将 Gradle 7.x 构建迁移到 Gradle 8.0 所需的信息。要从 Gradle 6.x 或更早版本迁移,请先完成旧版迁移指南

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

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

    Gradle 构建扫描的弃用视图

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

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

  2. 更新您的插件。

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

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

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

从 7.6 及更早版本升级

警告现在是错误

finalizedBy使用,mustRunAfter或引用包含的构建中的任务shouldRunAfter

现在,使用以下任何方法引用包含的构建中包含的任务都会导致执行时间错误:

  • finalizedBy

  • mustRunAfter

  • shouldRunAfter

从资源创建 TAR 树,无需备份文件

不再支持从没有后备文件的资源创建 TAR 树。相反,请将资源转换为文件并project.tarTree()在该文件上使用。有关详细信息,请参阅来自不带备份文件的资源的 TAR 树

使用无效的 Java 工具链规范

不再支持使用无效的 Java 工具链规范。通过确保在所有工具链规范上设置语言版本,可以避免相关的构建错误。请参阅用户手册了解更多信息。

在没有配置存储库的情况下使用自动工具链下载

不再支持在不明确提供要使用的存储库的情况下自动下载工具链。请参阅用户手册了解更多信息。

设置测试框架选项后更改测试框架现在会出现错误

当为 Java、Groovy 和 Scala 项目配置内置测试任务时,Gradle 不再允许您Test在配置选项后更改任务使用的测试框架。这已被弃用,因为它在某些情况下会默默地丢弃配置。

以下代码示例现在会产生错误:

test {
   options {
   }

   useJUnitPlatform()
}

相反,您可以:

test {
   // select test framework before configuring options
   useJUnitPlatform()
   options {
   }
}

此外,将测试框架多次设置为同一框架现在会累积可能在该框架上设置的任何选项。以前,每次设置框架时,都会导致框架选项被覆盖。

现在,以下代码会导致任务中包含“foo”和“bar”标签test

test {
   useJUnitPlatform {
        includeTags("foo")
   }
}
tasks.withType(Test).configureEach {
   // previously, this would overwrite the included tags to only include "bar"
   useJUnitPlatform {
        includeTags("bar")
   }
}

删除的 API

旧版 ArtifactTransform API

旧版ArtifactTransformAPI 已被删除。有关更多信息,请参阅注册工件转换扩展ArtifactTransform

旧版 IncrementalTask​​Inputs API

旧版IncrementalTaskInputsAPI 已被删除。有关详细信息,请参阅IncrementalTask​​Inputs 类型已弃用。此更改还会影响 Kotlin Gradle 插件和 Android Gradle 插件。对于 Gradle 8.0,您应该使用 Kotlin Gradle Plugin 1.6.10 或更高版本,以及 Android Gradle Plugin 7.3.0 with android.experimental.legacyTransform.forceNonIncremental=trueproperty 或更高版本。

旧版 AntlrSourceVirtualDirectory API

旧版AntlrSourceVirtualDirectoryAPI 已被删除。此更改会影响antlr插件。在 Gradle 8.0 及更高版本中,请改用AntlrSourceDirectorySet源集扩展。

Jvm插件助手

不需要 a 的类configureDocumentationVariantWithArtifact的已弃用方法已被删除。这是一个内部 API,但可能已被插件访问。相反,向该方法的重载版本提供 a 。JvmPluginsHelperFileResolverFileResolver

Groovydoc API 清理

isIncludePrivate任务类型的已弃用属性Groovydoc已被删除。而是将access属性与常量一起使用GroovydocAccess#PRIVATE

Java应用程序API清理

mainClassName接口的已弃用属性JavaApplication已被删除。而是使用该mainClass属性。

DefaultDomainObjectSet API 清理

已弃用的DefaultDomainObjectSet(Class)构造函数已被删除。这是一个内部 API,但可能已被插件使用。

JacocoPluginExtension API 清理

已弃用reportsDir的属性JacocoPluginExtension已被删除。而是使用该reportsDirectory属性。

DependencyInsightReportTask API 清理

legacyShowSinglePathToDependnecy任务类型的已弃用属性DependencyInsightReportTask已被删除。而是使用该showSinglePathToDependency属性。

报告和测试报告 API 清理

该类型已弃用的destination, 和属性已被删除。请改用和属性。enabledReportoutputLocationrequired

testResultDirs任务类型的已弃用属性TestReport已被删除。而是使用该testResults属性。

JacocoMerge 任务已删除

已弃用的JacocoMerge任务类型已被删除。该任务也可以使用相同的功能JacocoReport

JavaExec API 清理

main任务类型的已弃用属性JavaExec已被删除。而是使用该mainClass属性。

AbstractExecTask API 清理

任务类型已弃用的execResultgetter 属性AbstractExecTask已被删除。请改用executionResultgetter 属性。

AbstractTestTask API 清理

binResultsDir任务类型的已弃用属性AbstractTestTask已被删除。而是使用该binaryResultsDirectory属性。

SourceDirectorySet API 清理

outputDir该类型已弃用的属性SourceDirectorySet已被删除。而是使用该destinationDirectory属性。

VersionCatalog API 清理

该类型已弃用的findDependency(String)方法和dependencyAliases属性VersionCatalog已被删除。请改用findLibrary(String)方法和libraryAliases属性。

alias(String)该类型已弃用的方法VersionCatalogBuilder已被删除。请改用library(String, String, String)orplugin(String, String)方法。

WorkerExecutor API 清理

submit(Class, Action)接口中已弃用的方法WorkerExecutor已被删除。相反,WorkQueue通过noIsolation()classLoaderIsolation()、 和processIsolation()方法获取 a并使用submit(Class, Action)上的方法WorkQueue

DependencySubstitution API 清理

类型内部类型的已弃用with(ComponentSelector)方法已被删除。请改用该方法。DependencySubstitutionSubstitutionusing(ComponentSelector)

AbstractArchiveTask API 清理

任务类型已弃用的、appendixarchiveNamearchivePathbaseNameclassifierdestinationDir属性已被删除。请改用、、、、、和属性。extensionversionAbstractArchiveTaskarchiveAppendixarchiveFileNamearchiveFilearchiveBaseNamearchiveClassifierdestinationDirectoryarchiveExtensionarchiveVersion

IdeaModule API 清理

已弃用的类型testSourceDirstestResourceDirs属性IdeaModule已被删除。这会影响org.gradle.plugins.ide.idea.model.IdeaModule类型,而不是org.gradle.tooling.model.idea.IdeaModule类型。请改用testSourcestestResources属性。

AbstractCompile API 弃用

之前已弃用destinationDir的属性AbstractCompile仍然已弃用,现在将在使用时发出弃用警告。现在计划在 Gradle 9.0 中删除它。而是使用该destinationDirectory属性。

ResolvedComponentResult API 清理

getVariant接口中已弃用的方法ResolvedComponentResult已被删除。请改用该getVariants方法。

代码质量插件 API 清理

、和任务类型的已弃用antBuilder属性已被删除。请改用类型的属性。CheckstyleCodeNarcPmdProjectant

使用 API 清理

该类型已弃用的公共字段JAVA_API_CLASSESJAVA_API_JARSJAVA_RUNTIME_CLASSES和已被删除。这些值在内部类中可用,以便与以前发布的模块兼容,但不应用于任何新发布。JAVA_RUNTIME_JARSJAVA_RUNTIME_RESOURCESUsage JavaEcosystemSupport

外部依赖 API 清理

setForce(boolean)接口中已弃用的方法ExternalDependency已被删除。请改用该version(Action)方法来配置严格版本。

从 Kotlin DSL 中删除了构建扫描方法

已弃用的build-scan插件应用程序方法已从 Kotlin DSL 中删除。请改用该gradle-enterprise方法。

从 Kotlin DSL 中删除的配置扩展方法

Kotlin DSL 添加了专门的扩展方法,NamedDomainObjectProvider<Configuration>在按名称查找配置时可用。这些扩展允许构建在直接Configuration使用 a 的实例时访问 a 的某些属性NamedDomainObjectProvider<Configuration>

configurations.compileClasspath.files // equivalent to configurations.compileClasspath.get().files
configurations.compileClasspath.singleFile // equivalent to configurations.compileClasspath.get().singleFile

所有这些扩展都已从 API 中删除,但这些方法仍然可用于针对旧版本 Gradle 编译的插件。

  • NamedDomainObjectProvider<配置>.addToAntBuilder

  • NamedDomainObjectProvider<配置>.all

  • NamedDomainObjectProvider<配置>.allArtifacts

  • NamedDomainObjectProvider<配置>.allDependency

  • NamedDomainObjectProvider<配置>.allDependencyConstraints

  • NamedDomainObjectProvider<配置>.artifacts

  • NamedDomainObjectProvider<配置>.asFileTree

  • NamedDomainObjectProvider<配置>.asPath

  • NamedDomainObjectProvider<配置>.attributes

  • NamedDomainObjectProvider<配置>.buildDependency

  • NamedDomainObjectProvider<配置>.contains

  • NamedDomainObjectProvider<配置>.copy

  • NamedDomainObjectProvider<配置>.copyRecursive

  • NamedDomainObjectProvider<配置>.defaultDependencies

  • NamedDomainObjectProvider<配置>.依赖项

  • NamedDomainObjectProvider<配置>.dependencyConstraints

  • NamedDomainObjectProvider<配置>.description

  • NamedDomainObjectProvider<配置>.exclude

  • NamedDomainObjectProvider<配置>.excludeRules

  • NamedDomainObjectProvider<配置>.extendsFrom

  • NamedDomainObjectProvider<配置>.fileCollection

  • NamedDomainObjectProvider<配置>.files

  • NamedDomainObjectProvider<配置>.filter

  • NamedDomainObjectProvider<配置>.getTaskDependencyFromProjectDependency

  • NamedDomainObjectProvider<配置>.hierarchy

  • NamedDomainObjectProvider<配置>.incoming

  • NamedDomainObjectProvider<配置>.isCanBeConsumed

  • NamedDomainObjectProvider<配置>.isCanBeResolved

  • NamedDomainObjectProvider<配置>.isEmpty

  • NamedDomainObjectProvider<配置>.isTransitive

  • NamedDomainObjectProvider<配置>.isVisible

  • NamedDomainObjectProvider<配置>.minus

  • NamedDomainObjectProvider<配置>.outgoing

  • NamedDomainObjectProvider<配置>.plus

  • NamedDomainObjectProvider<配置>.resolutionStrategy

  • NamedDomainObjectProvider<配置>.resolve

  • NamedDomainObjectProvider<配置>.resolvedConfiguration

  • NamedDomainObjectProvider<配置>.setDescription

  • NamedDomainObjectProvider<配置>.setExtendsFrom

  • NamedDomainObjectProvider<配置>.setTransitive

  • NamedDomainObjectProvider<配置>.singleFile

  • NamedDomainObjectProvider<配置>.state

  • NamedDomainObjectProvider<配置>.withDependencies

您应该更喜欢直接引用 中的方法Configuration

潜在的重大变化

JavaForkOptions getJvmArgs()getAllJvmArgs()返回不可变列表

从接口检索的 JVM 参数列表JavaForkOptions现在是不可变的。

以前,对返回列表的修改会被默默地忽略。

可空注释更好地反映了 API 的实际可空性

在某些 API 中,未正确注释可为 null 性,并且允许 null 或返回 null 的 API 被标记为非 null。在 Java 或 Groovy 中,这种不匹配不会在编译时引起问题。在 Kotlin 中,这种不匹配使得有效代码难以编写,因为该语言不允许传递 null。

一个特殊的例子是null从 a Provider#mapor返回Provider#flatMap。在这两个 API 中,Gradle 都允许返回 null,但在 Kotlin DSL 中这被认为是非法的。

此更正可能会导致预期为非空的代码出现编译错误。

插件、任务和扩展类是抽象的

大多数插件、任务和扩展的公共类都已抽象化。这样做是为了更容易地从 Gradle 的实现中删除样板文件。

受此更改影响的插件也应该使其类抽象。只要对象是通过ObjectFactory或其他一些自动机制(如托管属性)实例化的,Gradle 就使用运行时类装饰来实现抽象方法。这些方法永远不应该直接实现。

包装器任务配置

如果gradle-wrapper.properties包含该distributionSha256Sum属性,则必须指定总和。您可以在包装的任务配置中或使用任务选项指定总和--gradle-distribution-sha256-sum

AbstractCodeQualityPlugin 类中的更改

AbstractCodeQualityPlugin.getJavaPluginConvention()Gradle 8.0 中删除了已弃用的方法。你应该改用JavaPluginExtension

删除--add-opensGradle 工作线程的隐式内容

在 Gradle 8.0 之前,JDK9+ 上的 Gradle Worker 自动打开 JDK 模块java.base/java.utiljava.base/java.lang通过传递--add-opensCLI 参数。这使得在 Gradle Worker 中执行的代码能够在 JDK 内部执行深度反射,而不会发出警告或失败。工人不再使用这些隐含的论点。

这会影响所有内部 Gradle 工作人员,这些工作人员用于执行各种任务:

新的警告和错误可能会出现在使用工作 API 对 JDK 内部进行深度反射的任何工具、扩展或插件中。

这些错误可以通过更新违规代码或依赖项来解决。更新可能包括:

  • 代码质量工具

  • 注释处理器

  • 任何使用worker API的Gradle插件

有关由于此更改而可能出现的错误或警告输出的一些示例,请参阅删除--add-opens测试工作人员的隐含内容。

SourceSet classesDirs 不再依赖于整个 SourceSet 作为任务依赖项

SourceSetOutput.classesDirs 在 Gradle 8.0 之前,包含不生成类文件的任务的任务依赖项。这意味着依赖于 的任务classesDirs也将依赖于classesprocessResources以及添加到 的任何其他任务依赖项SourceSetOutput。此行为可能是一个错误,因为该classesDirs属性不包含 的输出processResources。从 8.0 开始,这种隐式依赖关系被删除。现在,dependsclassesDirs仅执行直接在类目录中生成文件的任务。

考虑以下构建脚本:

plugins {
    id 'java-library'
}
// Task lists all files in the given classFiles FileCollection
tasks.register("listClassFiles", ListClassFiles) {
    classFiles.from(java.sourceSets.main.output.classesDirs)
}

以前,该listClassFiles任务取决于compileJavaprocessResourcesclasses。现在,仅compileJava是 的任务依赖性listClassFiles

如果构建中的某个任务依赖于先前的行为,您可以使用整个任务 SourceSetOutput作为输入,其中包含所有类和资源。

如果这不可行,您可以通过添加更多任务依赖项来恢复以前的行为classesDirs

java {
    sourceSets {
        main {
            output.classesDirs.builtBy(output)
        }
    }
}

最低支持的 Kotlin Gradle 插件版本已更改

Gradle 7.x 支持 Kotlin Gradle 插件 1.3.72 及更高版本。 1.6.21 以上的 Kotlin Gradle 插件版本未使用 Gradle 7.x 进行测试。 Gradle 8.x 支持 Kotlin Gradle 插件 1.6.10 及更高版本。您可以通过修改Kotlin编译任务中的语言版本和api版本设置来使用较低的Kotlin语言版本。

支持的最低 Android Gradle 插件版本已更改

Gradle 7.x 支持 Android Gradle 插件 (AGP) 4.1 及更高版本。 7.3 以上的 AGP 版本未使用 Gradle 7.x 进行测试。 Gradle 8.x 支持 AGP 8 及更高版本。如果配置以下属性,Gradle 8.x 支持 AGP 7.3 及更高版本:

android.experimental.legacyTransform.forceNonIncremental=true

更改AntBuilder为父类

以前,org.gradle.api.AntBuilder扩展了已弃用的groovy.util.AntBuilder类。现在它延伸了groovy.ant.AntBuilder

PluginDeclaration不可序列化

org.gradle.plugin.devel.PluginDeclaration不再可序列化。如果需要序列化它,可以将其转换为您自己的可序列化类。

Gradle 在最新检查中不使用 equals 来表示序列化值

Gradle 现在在最新检查中比较序列化值时不会尝试使用 equals。有关详细信息,请参阅不推荐使用依赖 equals 进行最新检查

Gradle 7.x 中引入的任务和转换验证警告现在是错误

Gradle 在 Gradle 7.x 系列中引入了额外的任务和工件转换验证警告。这些警告现在在 Gradle 8.0 中是错误,并且会使构建失败。

变成错误的警告:

Gradle 不会忽略文件树的空目录@SkipWhenEmpty

以前,Gradle 用于检测注释的输入文件集合是否@SkipWhenEmpty仅包含文件树,然后自动忽略目录。要忽略 Gradle 8.0 及更高版本中的目录,需要使用 显式注释 input 属性@IgnoreEmptyDirectories。有关详细信息,请参阅文件树和空目录处理

JavaVersionJava 9 和 Java 10的格式已更改

的字符串格式JavaVersion已更改以匹配官方 Java 版本控制。从Java 9开始,语言版本不能包含前缀1.。这会影响任务和 的sourceCompatiblity​​ 和targetCompatibility属性的格式。从字符串解析 时,仍然支持旧格式。JavaCompileJavaExtensionJavaVersion

摇篮7.6

摇篮8.0

1.8

1.8

1.9

9

1.10

10

11

11

预编译脚本插件默认使用严格的 Kotlin DSL 访问器生成

在预编译脚本插件中,如果插件无法应用,类型安全的 Kotlin DSL 访问器生成现在会导致构建失败。

从 Gradle 7.6 开始,构建可以通过org.gradle.kotlin.dsl.precompiled.accessors.strict系统属性启用此行为。此行为现​​在是默认行为。该属性已被弃用,应删除其使用。您可以在下面找到有关此属性的更多信息。

初始化脚本应用于buildSrc构建

使用指定的初始化脚本--init-script现在应用于buildSrc构建。在以前的版本中,这些适用于包含的构建,但不适用于“buildSrc 构建”。

此行为现​​在对于buildSrc并包含的构建是一致的。

Gradle 不再运行构建build任务buildSrc

当 Gradle 构建输出时,buildSrc它仅运行产生该输出的任务,这通常是jar任务。在以前的版本中,Gradle 将运行该build任务。

这意味着其子项目的测试buildSrc不会自动构建和执行,现在必须明确请求。

此行为现​​在对于buildSrc并包含的构建是一致的。

buildSrc您可以使用与包含的构建中的项目相同的方式运行测试,例如通过运行gradle buildSrc:build.

buildFinished { }buildSrc所有任务执行后运行的钩子

buildFinished {}现在,钩子在buildSrc所有任务完成后运行。在以前的版本中,此挂钩将在任务buildSrc完成之后和任何请求的任务开始之前立即运行。

此行为现​​在对于buildSrc并包含的构建是一致的。

包含构建的路径的更改

为了更好地处理嵌套包含构建名称之间的冲突,Gradle 现在使用包含构建的目录层次结构来分配构建路径。如果您在嵌套包含的构建中从命令行运行任务,那么您可能需要调整您的调用。

例如,如果您有以下层次结构:

.
├── settings.gradle.kts
└── nested
    ├── settings.gradle.kts
    └── nestedNested
        └── settings.gradle.kts
settings.gradle.kts
includeBuild("nested")
nested/settings.gradle.kts
includeBuild("nestedNested")
.
├── settings.gradle
└── nested
    ├── settings.gradle
    └── nestedNested
        └── settings.gradle
settings.gradle
includeBuild("nested")
nested/settings.gradle
includeBuild("nestedNested")

在 Gradle 8.0 之前,您运行gradle :nestedNested:compileJava.在 Gradle 8.0 中,调用更改为gradle :nested:nestedNested:compileJava.

现在jst.ejb使用插件添加会删除方面eclipse wtpjst.utility

eclipse wtp插件将jst.utilityfacet添加到java项目中。现在,添加jst.ejb构面会隐式删除该jst.utility构面:

eclipse {
    wtp {
        facet {
            facet name: 'jst.ejb', version: '3.2'
        }
    }
}

简化 PMD 自定义规则配置

以前,您必须显式配置 PMD 以忽略带有ruleSets = [].在 Gradle 8.0 中,将ruleSetConfig或设置ruleSetFiles为非空值会隐式忽略默认规则。

报表getOutputLocation返回类型从 Provider 更改为 Property

ReportoutputLocation的属性现在返回 type 的值。以前,返回类型为 的值。Property<? extends FileSystemLocation>outputLocationProvider<? extends FileSystemLocation>

此更改使报告 API 内部更加一致,并允许对报告任务进行更惯用的配置。

以前的,现在的@Deprecated用法:

tasks.named('test') {
    reports.junitXml.setDestination(layout.buildDirectory.file('reports/my-report-old').get().asFile) // DEPRECATED
}

可以替换为:

tasks.named('test') {
    reports.junitXml.outputLocation = layout.buildDirectory.dir('reports/my-report')
}

许多内置和自定义报告(例如 JUnit 使用的报告)都实现了此接口。针对包含先前方法签名的早期版本的 Gradle 编译的插件可能需要重新编译才能与包含新签名的较新版本的 Gradle 一起使用。

删除了外部插件验证插件

孵化插件ExternalPluginValidationPlugin已被删除。使用java-gradle-pluginvalidatePlugins任务来验证正在开发的插件。

与过go的版本相比,可复制的存档可能会发生变化

Gradle 将用于创建档案的压缩库从基于 Ant 的压缩库更改为Apache Commons Compress™。因此,从相同内容创建的存档最终不太可能与使用旧库创建的旧版本逐字节相同。

升级到 Kotlin 1.8.10

嵌入式 Kotlin 已更新至Kotlin 1.8.10。另请参阅Kotlin 1.8.0发行说明。有关更多信息,请参阅 Kotlin 的发行说明

将 Kotlin DSL 更新至 Kotlin API 级别 1.8

此前,Kotlin DSL 使用 Kotlin API 级别 1.4。从 Gradle 8.0 开始,Kotlin DSL 使用 Kotlin API 级别 1.8。这一变化带来了自 Kotlin 1.4.0 以来对 Kotlin 语言和标准库所做的所有改进。

有关此升级中的重大变更和非重大变更的信息,请参阅以下 Kotlin 文档链接:

请注意,Kotlin Gradle 插件 1.8.0 开始使用 Java 工具链。建议您配置工具链,而不是在 Kotlin 项目中定义 Java sourceCompatibility/ 。targetCompatibility

另请注意,Kotlin Gradle 插件 1.8.0 引入了惰性配置属性,作为不支持惰性配置compilerOptions的替代品。kotlinOptions建议您使用compilerOptions而不是配置 Kotlin 编译kotlinOptions

kotlinDslPluginOptions.jvmTarget已弃用

以前,您可以kotlinDslPluginOptions.jvmTarget在使用插件时配置应使用哪个 JVM 目标来编译代码kotlin-dsl

从 Gradle 8.0 开始,kotlinDslPluginOptions.jvmTarget已弃用。您应该配置一个 Java 工具链

如果您已经配置并kotlinDslPluginOptions.jvmTarget取消设置了 Java 工具链,那么 Gradle 8.0 现在将使用 Java 工具链作为 JVM 目标,而不是之前的默认目标 (1.8)。

Java Base Plugin 现在设置 Jar、War 和 Ear 目标目录默认值

以前,该base插件将 JarWarEar任务的 目标目录配置为BasePluginExtension#getLibsDirectory指定的目录 。在 Gradle 8.0 中,处理此配置。对于已经通过、、或其他 JVM 生态系统插件直接或间接应用该插件的项目,无需进行任何更改 。java-basejava-basejavaapplicationjava-library

不应使用上传任务

Upload任务仍然已弃用,现在计划在 Gradle 9.0 中删除。尽管此类型仍然存在,但它不再起作用,并且在运行时会抛出异常。保留它只是为了避免破坏插件。请改用maven-publish或插件中的任务ivy-publish

不再允许配置作为依赖项

不再允许将配置添加为dependenciesDSL 块中的依赖项,或以编程方式使用类DependencyHandler的方法,并且将失败并出现异常。doAdd(Configuration, Object, Closure)要复制此行为的许多方面,请改为使用extendsFrom(Configuration)on 方法扩展配置Configuration

已弃用的消耗配置现在是非消耗配置

以下配置永远不会被使用:

  • antlr创建的配置AntlrPlugin

  • zinc创建的配置ScalaBasePlugin

  • 创建的providedCompile和配置providedRuntimeWarPlugin

这些配置已被弃用,现在不再可供使用。尝试使用它们将导致错误。

相同的耗材配置现在是一个错误

如果项目具有多个共享相同属性和功能声明的可用配置,则在发布或解析为该项目的依赖项时,构建将会失败。这以前已被弃用

outgoingVariants报告将对受影响的配置发出警告。

JVM 项目的基于工具链的任务

从 Gradle 8.0 开始,所有具有工具链支持的核心 Java 任务现在都无条件使用工具链。如果JavaBasePlugin应用,则任务上工具属性的约定值由扩展上配置的工具链定义java。如果没有显式配置工具链,则使用与运行 Gradle 的 JVM 对应的工具链。

同样,Groovy 和 Scala 插件中的任务也依赖于工具链来确定它们在哪个 JVM 上执行。

Scala 编译目标

通过上述工具链的更改,Scala 编译任务现在始终提供一个targetorrelease参数。确切的参数和值取决于工具链的使用与否以及 Scala 版本。

有关详细信息,请参阅Scala 插件文档

pluginBundle放入 Plugin Publish 插件中

Gradle 8 不再支持该pluginBundle扩展。其功能已合并到gradlePlugin块中。这些更改需要最新版本的 Plugin Publish 插件 ( 1.0.+ )。有关配置插件发布的文档可以在门户网站用户手册中找到。

从 7.5 及更早版本升级

AttributeSchema.setAttributeDisambiguationPrecedence(List)and方法AttributeSchema.getAttributeDisambiguationPrecedence()现在接受并返回List而不是Collection更好地指示这些集合中元素的顺序很重要。

严格的 Kotlin DSL 预编译脚本插件访问器生成

如果预编译脚本中请求的插件未能应用,则默认情况下,预编译脚本插件的类型安全 Kotlin DSL 访问器生成不会使构建失败。由于原因可能是环境问题以及向后兼容性原因,因此这种行为尚未改变。

回到 Gradle 7.1,:generatePrecompiledScriptPluginAccessors负责生成访问器的任务默认被标记为不可缓存。引入系统org.gradle.kotlin.dsl.precompiled.accessors.strict属性是为了提供一个选择加入更严格的操作模式,当插件应用程序失败时,构建会失败,并为该任务启用构建缓存。

从 Gradle 7.6 开始,Kotlin DSL 预编译脚本插件的非严格访问器生成已被弃用。这将在 Gradle 8.0 中改变。严格的访问器生成将成为默认设置。要选择严格行为,请将“org.gradle.kotlin.dsl.precompiled.accessors.strict”系统属性设置为true

gradle.properties这可以在构建根目录中的文件中持久地实现:

systemProp.org.gradle.kotlin.dsl.precompiled.accessors.strict=true

潜在的重大变化

升级到 Kotlin 1.7.10

嵌入式 Kotlin 已更新至Kotlin 1.7.10

Gradle 不附带,kotlin-gradle-plugin但升级到 1.7.10 可以带来新版本。例如,当您使用kotlin-dsl插件时。

1.7.10版本kotlin-gradle-plugin更改了任务类型的类型层次结构KotlinCompile。它不再延伸AbstractCompile。如果您以前选择 Kotlin 编译任务,AbstractCompile则需要将其更改为KotlinCompile.

例如,这个

tasks.named<AbstractCompile>("compileKotlin")

需要改为

tasks.named<KotlinCompile>("compileKotlin")

同样,如果您以前通过以下方式过滤任务,AbstractCompile您将不再获得 Kotlin 编译任务:

tasks.withType<AbstractCompile>().configureEach {
    // ...
}

需要改为

tasks.withType<AbstractCompile>().configureEach {
    // ...
}
tasks.withType<KotlinCompile>().configureEach {
    // ...
}

升级到 Groovy 3.0.13

Groovy 已更新至Groovy 3.0.13

由于之前的版本是 3.0.10,因此还包括3.0.113.0.12 的更改。

升级到 CodeNarc 3.1.0

CodeNarc 的默认版本已更新至3.1.0

升级到PMD 6.48.0

PMD 已更新至PMD 6.48.0

配置不存在的可执行文件现在失败

JavaCompile当为或任务显式配置可执行文件时Test,如果该可执行文件不存在,Gradle 现在将发出错误。过go,任务将使用默认工具链或运行构建的 JVM 来执行。

测试套件中依赖项声明的更改

作为不断发展测试套件的努力的一部分,测试套件dependencies块中的依赖项声明现在是强类型的。这将有助于使这个正在孵化的 API 在 IDE 中更容易被发现和使用。

在某些情况下,这需要更改语法。例如,使用以下语法构建先前添加测试套件依赖项的脚本:

testing {
  suites {
    register<JvmTestSuite>("integrationTest") {
      dependencies {
        implementation(project)
      }
    }
  }
}

现在将无法编译,并显示如下消息:

None of the following functions can be called with the arguments supplied:
public operator fun DependencyAdder.invoke(dependencyNotation: CharSequence): Unit defined in org.gradle.kotlin.dsl
public operator fun DependencyAdder.invoke(dependency: Dependency): Unit defined in org.gradle.kotlin.dsl
public operator fun DependencyAdder.invoke(files: FileCollection): Unit defined in org.gradle.kotlin.dsl
public operator fun DependencyAdder.invoke(dependency: Provider<out Dependency>): Unit defined in org.gradle.kotlin.dsl
public operator fun DependencyAdder.invoke(externalModule: ProviderConvertible<out MinimalExternalModuleDependency>): Unit defined in org.gradle.kotlin.dsl

要解决此问题,请将对的引用替换project为对 的调用project()

testing {
  suites {
    register<JvmTestSuite>("integrationTest") {
      dependencies {
        implementation(project())
      }
    }
  }
}

受此更改影响的其他语法包括:

  • 您不能用作Provider<String>依赖项声明。

  • 您不能使用 aMap作为 Kotlin 或 Java 的依赖声明。

  • 您不能直接使用包作为依赖项声明 ( implementation(libs.bundles.testing))。代替使用implementation.bundle(libs.bundles.testing)

有关更多信息,请参阅用户指南的 JVM 测试套件插件部分和DSL 参考中的页面中更新的声明附加测试套件示例。DependencyAdder

弃用

现已弃用无效 Java 工具链规范的使用

除了 Java 语言版本之外,Java 工具链DSL 还允许配置其他标准​​,例如特定供应商或 VM 实现。从 Gradle 7.6 开始,配置其他属性而不指定语言版本的工具链规范将被视为无效。无效的规范已被弃用,并将在 Gradle 8.0 中成为构建错误。

有关工具链配置的更多详细信息,请参阅用户手册

包中已弃用的成员org.gradle.util现在报告其弃用情况

这些成员将在 Gradle 9.0 中删除。

  • ClosureBackedAction

  • CollectionUtils

  • ConfigureUtil

  • DistributionLocator

  • GFileUtils

  • GradleVersion.getBuildTime()

  • GradleVersion.getNextMajor()

  • GradleVersion.getRevision()

  • GradleVersion.isValid()

  • GUtil

  • NameMatcher

  • NameValidator

  • RelativePathUtil

  • TextUtil

  • SingleMessageLogger

  • VersionNumber

  • WrapUtil

内部 DependencyFactory 已重命名

内部org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory类型已重命名为org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal.作为内部类型,不应使用它,但出于兼容性原因,内部ClassPathNotation类型仍然可用。此类型名称已弃用,并将在 Gradle 8.0 中删除。其公共 API 位于 on ,具有提供相同功能DependencyHandler等方法。localGroovy()

替换集合在org.gradle.plugins.ide.idea.model.IdeaModule

testResourcesDirs字段testSourcesDirs及其 getter 和 setter 已被弃用。将用法替换为现在稳定的getTestSources()andgetTestResources()方法及其各自的设置器。这些新方法返回并由ConfigurableFileCollection实例支持,以提高使用的灵活性。 Gradle 现在会在使用这些已弃用的方法时发出警告。它们将在 Gradle 的未来版本中删除。

更换方法在org.gradle.api.tasks.testing.TestReport

getDestinationDir()setDestinationDir(File)getTestResultDirs()方法setTestResultDirs(Iterable)已被弃用。将用法替换为现在稳定的getDestinationDirectory()andgetTestResults()方法及其关联的设置器。这些已弃用的元素将在 Gradle 的未来版本中删除。

不推荐使用某些配置块中对外部作用域方法的隐式引用

在 Gradle 7.6 之前,Groovy 脚本允许访问命名容器配置方法中的根项目配置方法,这些方法会抛出“MissingMethodException”。请考虑以下片段作为此行为的示例:

当提供的闭包对于配置来说是无效的配置闭包时, Gradle 允许repositories从块内访问顶级块。configurations在这种情况下,repositories闭包的执行就像在脚本级别调用一样,并创建一个未配置的repositories配置:

configurations {
    repositories {
        mavenCentral()
    }
    someConf {
        canBeConsumed = false
        canBeResolved = false
    }
}

该行为也适用于不立即执行的闭包。在这种情况下,afterResolve仅在任务运行时执行resolve。该distributions闭包是一个有效的顶级脚本闭包。但这对于配置来说是一个无效的配置闭包。此示例conf立即创建配置。在resolve任务执行期间,distributions块的执行就像在脚本级别声明一样:

configurations {
    conf.incoming.afterResolve {
        distributions {
            myDist {
                contents {}
            }
        }
    }
}

task resolve {
    dependsOn configurations.conf
    doFirst {
        configurations.conf.files() // Trigger `afterResolve`
    }
}

从 Gradle 7.6 开始,此行为已被弃用。从 Gradle 8.0 开始,此行为将被删除。相反,Gradle 会抛出底层MissingMethodException.为了缓解这种变化,请考虑以下解决方案:

configurations {
    conf.incoming.afterResolve {
        // Fully qualify the reference.
        project.distributions {
            myDist {
                contents {}
            }
        }
    }
}
configurations {
    conf
}

// Extract the script-level closure to the script root scope.
configurations.conf.incoming.afterResolve {
    distributions {
        myDist {
            contents {}
        }
    }
}

从 7.4 及更早版本升级

IncrementalTask​​Inputs 类型已弃用

IncrementalTaskInputs类型用于实现增量任务,也就是说可以优化为在更改的输入的子集而不是整个输入上运行的任务。这种类型有许多缺点。特别是使用这种类型时,无法确定更改与哪个输入相关联。

您现在应该改用该InputChanges类型。有关更多详细信息,请参阅用户指南中有关实施增量任务的部分。

潜在的重大变化

版本目录仅接受单个 TOML 导入文件

使用导入方法时仅接受单个文件from。这意味着解析为多个文件的符号(例如,当传递多个文件时的Project.files(java.lang.Object…​)方法)将导致构建失败。

更新默认工具集成版本

插件生成的类路径文件eclipse已更改

测试配置中定义的项目依赖项获取test=true类路径属性。默认情况下,JVM 测试套件插件定义的所有源集和依赖项也被标记为测试代码。您现在可以通过插件 DSL 自定义测试源集和依赖项eclipse

eclipse {
    classpath {
        testSourceSets = [sourcesSets.test, sourceSets.myTestSourceSet]
        testConfigurations = [configuration.myTestConfiguration]
    }
}

或者,您可以调整或删除eclipse.classpath.file.whenMerged { }块中的类路径属性。

使用 GPG 命令时,签名插件默认为gpg而不是gpg2

使用 GPG 命令时签名插件的默认可执行文件从 更改gpg2gpg。随着 GPG 2.x 变得稳定,并且发行版开始通过不链接可执行文件进行迁移,引发了这一变化gpg2

为了设置旧的默认值,可以在以下位置手动定义可执行文件gradle.properties

signing.gnupg.executable=gpg2

mustRunAfterfinalizedBy依赖关系不再违反约束

在以前的 Gradle 版本中,mustRunAfter常规任务和终结器任务依赖项之间的约束不会得到遵守。

作为一个具体示例,请考虑以下任务图定义:

tasks {
    register("dockerTest") {
        dependsOn("dockerUp")     // dependsOn createContainer mustRunAfter removeContainer
        finalizedBy("dockerStop") // dependsOn removeContainer
    }

    register("dockerUp") {
        dependsOn("createContainer")
    }

    register("dockerStop") {
        dependsOn("removeContainer")
    }

    register("createContainer") {
        mustRunAfter("removeContainer")
    }

    register("removeContainer") {
    }
}

相关限制是:

  • dockerStop是 的终结器,dockerTest因此必须在dockerTest;之后运行

  • removeContainer是 的依赖项dockerStop,因此必须在 之前运行dockerStop

  • createContainer必须追赶removeContainer

在 Gradle 7.5 之前,gradle dockerTest将产生以下执行顺序,违反和mustRunAfter之间的约束::createContainer:removeContainer

> Task :createContainer UP-TO-DATE
> Task :dockerUp UP-TO-DATE
> Task :dockerTest UP-TO-DATE
> Task :removeContainer UP-TO-DATE
> Task :dockerStop UP-TO-DATE

从 Gradle 7.5 开始,mustRunAfter完全遵守约束,产生以下执行顺序:

> Task :removeContainer UP-TO-DATE
> Task :createContainer UP-TO-DATE
> Task :dockerUp UP-TO-DATE
> Task :dockerTest UP-TO-DATE
> Task :dockerStop UP-TO-DATE

Scala Zinc 版本更新至 1.6.1

Zinc 是 Scala 增量编译器,它允许 Gradle 始终编译当前文件更改所需的最小文件集。它考虑了正在使用的方法和已更改的方法,这意味着它比文件间依赖关系更精细。

Zinc 版本已更新到最新的可用版本,以便从最近的所有错误修复中受益。因此,如果您使用zincVersion设置,建议删除它并仅使用默认版本,因为 Gradle 只能编译 Zinc 版本设置为 1.6.x 或更高版本的 Scala 代码。

删除--add-opens测试工作人员的隐含内容

在 Gradle 7.5 之前,JDK 模块java.base/java.util和是通过传递CLI 参数java.base/java.lang在 JDK9+ 上的测试工作线程中自动打开的。--add-opens这意味着任何测试都能够对 JDK 内部进行深度反射,而不会发出警告或失败。这导致测试不可靠,因为在生产环境中代码会失败,而代码却允许通过。

这些隐式参数已被删除,默认情况下不再添加。如果您的代码或任何依赖项在测试执行期间对 JDK 内部执行深度反射,您可能会看到以下行为更改:

在 Java 16 之前,会显示新的构建警告。这些新警告将打印到 stderr 并且不会导致构建失败:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.ReflectUtils$2 (file:/.../testng-5.12.1.jar) to <method>
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.ReflectUtils$2
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

对于 Java 16 或更高版本,会引发构建失败的异常:

// Thrown by TestNG
java.lang.reflect.InaccessibleObjectException: Unable to make <method> accessible: module java.base does not "opens java.lang" to unnamed module @1e92bd61
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
	at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
    ...

// Thrown by ProjectBuilder
org.gradle.api.GradleException: Could not inject synthetic classes.
	at org.gradle.initialization.DefaultLegacyTypesSupport.injectEmptyInterfacesIntoClassLoader(DefaultLegacyTypesSupport.java:91)
	at org.gradle.testfixtures.internal.ProjectBuilderImpl.getGlobalServices(ProjectBuilderImpl.java:182)
	at org.gradle.testfixtures.internal.ProjectBuilderImpl.createProject(ProjectBuilderImpl.java:111)
	at org.gradle.testfixtures.ProjectBuilder.build(ProjectBuilder.java:120)
	...
Caused by: java.lang.RuntimeException: java.lang.IllegalAccessException: module java.base does not open java.lang to unnamed module @1e92bd61

在大多数情况下,可以通过更新执行非法访问的代码或依赖项来解决这些错误。如果正在测试的代码或相关依赖项的最新版本通过设计执行非法访问,则可以通过使用以下命令手动打开java.base/java.langjava.base/java.util模块来恢复旧行为--add-opens

tasks.withType(Test).configureEach {
    jvmArgs(["--add-opens=java.base/java.lang=ALL-UNNAMED",
             "--add-opens=java.base/java.util=ALL-UNNAMED"]
}

如果您正在开发 Gradle 插件,则ProjectBuilder依赖于java.base/java.lang模块中的反射。应用插件时,Gradle 会自动--add-opens向测试添加适当的标志。java-gradle-plugin

如果您使用TestNG,则之前的版本会5.14.6执行非法反射。更新到至少5.14.6应该修复不兼容性。

Checkstyle 任务使用工具链并默认并行执行

Checkstyle插件现在使用 Gradle 工作 API 将 Checkstyle 作为外部工作进程运行。多个 Checkstyle 任务现在可以在一个项目中并行运行。

某些项目需要增加 Checkstyle 可用的内存量,以避免内存不足错误。您可以通过设置Checkstyle 任务的来增加 Checkstyle 进程的最大内存maxHeapSize。默认情况下,该进程将以 512MB 的最大堆大小启动。

我们还建议将 Checkstyle 更新到版本 9.3 或更高版本。

运行 Checkstyle 时缺少用相对路径指定的文件

Gradle 7.5 一致将 Checkstyle 任务的当前工作目录设置为.这可能会导致自定义 Checkstyle 任务或采用不同目录作为相对路径的 Checkstyle 配置文件出现问题。$GRADLE_USER_HOME/workers

以前,Gradle 根据运行 Gradle 的目录选择当前工作目录。如果您在以下位置运行 Gradle:

  • 项目的根目录:Gradle 使用根目录作为当前工作目录。

  • 项目的嵌套目录:Gradle 使用子项目的根目录作为当前工作目录。

在版本 7.5 及更高版本中,Gradle 始终将 Checkstyle 任务的当前工作目录设置为.$GRADLE_USER_HOME/workers

弃用

将文件转换为类路径,其中路径包含文件分隔符

Java 具有路径分隔符的概念,用于分隔路径列表中的各个路径,例如在类路径字符串中。各个路径不得包含路径分隔符。因此, 不推荐使用包含路径分隔符的路径的文件,并且在 Gradle 8.0 及更高版本中这将是一个错误。使用包含路径分隔符的路径的文件集合可能会导致错误的构建,因为 Gradle 找不到文件作为输入,甚至在包含路径分隔符的路径在操作系统上非法时导致构建失败。@FileCollection.getAsPath()

dependencyInsight --singlepath选项已弃用

为了保持一致性,已将其更改为--single-path. API 方法保持不变,这只影响 CLI。

GroovydocincludePrivate属性已弃用

有一个新access属性可以更好地控制 Groovydoc 中包含的内容。

必须使用基于提供程序的 API 在配置时运行外部进程

当启用配置缓存时,现在不推荐使用Project.execProject.javaexec和标准 Java 和 Groovy API 在配置时运行外部进程。在 Gradle 8.0 及更高版本中这将是一个错误。 Gradle 7.5 引入了配置缓存兼容的方法,通过基于提供者的 API或接口的自定义实现来执行和获取外部进程的输出ValueSource。配置缓存章节提供了更多详细信息,可帮助迁移到新 API。

从 7.3 及更早版本升级

弃用

采用OpenJDK工具链下载

从 AdoptOpenJDK 迁移到 Adoptium 后,在 Eclipse 基础下,不再可能从其端点下载 AdoptOpenJDK 版本。相反,会返回 Eclipse Temurin 或 IBM Semeru 构建。

当在工具链规范中指定 AdoptOpenJDK 供应商并且自动配置使用它时,Gradle 7.4+ 现在将发出弃用警告。如果必须使用AdoptOpenJDK,则应关闭自动下载。如果 Eclipse Temurin 或 IBM Semeru 构建适合您,请指定JvmVendorSpec.ADOPTIUMJvmVendorSpec.IBM作为供应商,或不指定供应商。

文件树和空目录处理

在输入文件集合上使用时,Gradle 在确定输入为空时会跳过该任务。如果输入文件集合仅包含文件树,Gradle 会忽略目录进行空性检查。尽管在检查输入文件集合的更改时,Gradle 仅在存在注释时忽略目录。@SkipWhenEmpty@IgnoreEmptyDirectories

@SkipWhenEmptyGradle 现在将忽略检查和一致确定更改的目录。在 Gradle 8.0 之前,Gradle 会检测注释的输入文件集合是否@SkipWhenEmpty仅包含文件树,然后自动忽略目录。此外,Gradle 会发出弃用警告,告知用户 Gradle 8.0 中的行为将发生变化,并且输入属性应使用@IgnoreEmptyDirectories.要忽略 Gradle 8.0 及更高版本中的目录,需要使用 .input 属性进行注释@IgnoreEmptyDirectories

最后,使用implied ,因此使用此注释时无需进行任何更改。通过运行时 API 注册输入目录时也是如此。@InputDirectory@IgnoreEmptyDirectoriesinputs.dir()

不推荐使用没有 FileResolver 的 LazyPublishArtifact

当使用不带 FileResolver 的 LazyPublishArtifact 时,会使用不同的文件解析策略,这会重复 FileResolver 中的某些逻辑。

为了提高一致性,LazyPublishArtifact 应与 FileResolver 一起使用,并且将来会需要它。

这也会影响使用 LazyPublishArtifact 的其他内部 API,这些 API 现在也会在需要时发出弃用警告。

来自资源的 TAR 树,无需备份文件

可以从任意资源创建 TAR 树。如果资源不是通过 创建的project.resources,那么它可能没有备份文件。不推荐从没有后备文件的资源创建 TAR 树。相反,请将资源转换为文件并project.tarTree()在该文件上使用。要将资源转换为文件,您可以使用自定义任务或使用依赖项管理通过 URL 下载文件。这样,Gradle 就能够应用最新检查等优化,而不是每次都重新运行逻辑来创建资源。

独特的属性集

与项目内的消耗性配置关联的Attribute集在该项目内共享同一Capability集的所有其他配置中必须是唯一的。

这将在配置变体配置结束时进行检查,因为它们被锁定以防止进一步的突变。

如果这组属性在配置之间共享,请考虑向其中一个变体添加附加属性,其唯一目的是消除歧义。

Provider#forUseAtConfigurationTime()已被弃用

Provider#forUseAtConfigurationTime现已弃用,并计划在 Gradle 9.0 中删除。客户只需删除该呼叫即可。

该调用对于外部值的提供者是强制性的,例如系统属性环境变量Gradle 属性文件内容,这些外部值将在配置时与配置缓存功能一起使用。

从 7.4 版开始,Gradle 将隐式地将配置时使用的外部值视为配置缓存输入。

客户端还可以自由使用标准 Java API,例如System#getenv读取环境变量、System#getProperty读取系统属性以及 Gradle API,例如Project#property(String)Project#findProperty(String)配置时读取 Gradle 属性。基于APIProvider仍然是将外部值连接到任务输入以实现最大配置缓存重用的推荐方法。

任务执行监听器和事件

Gradle 配置缓存不支持直接访问实例的侦听器和事件TaskProject这允许 Gradle 并行执行任务并在配置缓存中存储最少量的数据。为了实现无论配置缓存是否启用都保持一致的 API,以下 API 已被弃用,并将在 Gradle 8.0 中被删除或出现错误:

有关如何将这些用法迁移到配置缓存支持的 API 的详细信息,请参阅配置缓存章节。

构建已完成的事件

Gradle 配置缓存不支持构建完成的侦听器。因此,以下 API 已弃用并将在 Gradle 8.0 中删除:

有关如何将这些用法迁移到配置缓存支持的 API 的详细信息,请参阅配置缓存章节。

Task.getProject()从任务操作调用

现在已弃用在执行时从任务操作调用Task.getProject(),并且在 Gradle 8.0 中将出现错误。该方法可以在配置时使用,但建议避免这样做。

有关如何将这些用法迁移到配置缓存支持的 API 的详细信息,请参阅配置缓存章节。

Task.getTaskDependencies()从任务操作调用

现在已弃用在执行时从任务操作调用Task.getTaskDependency(),并且在 Gradle 8.0 中将出现错误。该方法可以在配置时使用,但建议避免这样做。

有关如何将这些用法迁移到配置缓存支持的 API 的详细信息,请参阅配置缓存章节。

Task.usesService在没有相应声明的情况下使用任务中的构建服务

Gradle 需要这些信息,以便它能够正确遵守构建服务生命周期及其使用限制。

这将成为未来 Gradle 版本中的错误。

查看共享构建服务文档以获取更多信息。

VersionCatalog 和 VersionCatalogBu​​ilder 弃用

VersionCatalogVersionCatalogBu​​ilder中的一些方法现已弃用,并计划在 Gradle 8.0 中删除。具体替换可以在受影响方法的 JavaDoc 中找到。

libs.versions.toml更改这些方法是为了提高文件和 API 类之间的一致性。

从 7.2 及更早版本升级

潜在的重大变化

更新捆绑的 Gradle 依赖项

plugins块中插件的应用顺序

块中插件的实际应用顺序plugins不一致,并且取决于插件如何添加到类路径中。

现在,插件始终按照在plugins块中声明的顺序应用,这在极少数情况下可能会改变现有构建的行为。

依赖解析中排除对替换依赖的影响

在此版本之前,无法从依赖关系图中排除依赖关系替换目标。这是由于在执行替换之前检查排除项而导致的。现在 Gradle 还将检查替换结果的排除情况。

版本目录

生成的访问器不再提供对类型不安全 API 的访问。您必须改用版本目录扩展

Scala 中的工具链支持

在 Scala 中使用工具链时,-targetScala 编译器的选项现在将自动设置。这意味着使用 Scala 版本无法定位的 Java 版本将导致错误。在编译器选项中提供此标志将禁用此行为,并允许使用较高的 Java 版本来编译较低的字节码目标。

声明包含不可读内容的输入或输出目录

对于最新检查,Gradle 依赖于跟踪任务的输入和输出的状态。 Gradle 过go常常忽略输入或输出中的不可读文件以支持某些用例,尽管它无法跟踪它们的状态。不推荐在包含不可读内容的任务上声明输入或输出目录,现在通过声明任务不被跟踪来支持这些用例。使用 @UntrackedTask注解Task.doNotTrackState()方法将任务声明为未跟踪。

当您使用Copy任务将单个文件复制到包含不可读文件的目录中时,请使用方法Task.doNotTrackState()

从 7.1 及更早版本升级

潜在的重大变化

应用程序启动脚本和 Gradle 包装器脚本的安全更改

由于CVE-2021-32751、 Gradle 的应用程序插件生成的启动脚本已更新gradle,以避免当攻击者能够更改环境变量时这些脚本可用于执行任意代码。gradlew

您可以使用最新版本的 Gradle 生成gradlew脚本并使用它来执行旧版本的 Gradle。

这对于大多数用户来说应该是透明的;但是,依赖于环境变量JAVA_OPTSGRADLE_OPTS通过复杂的引号转义传递参数的 Gradle 构建可能会发生变化。如果您怀疑某些东西破坏了您的构建并且无法找到解决方案,请联系我们。

更新捆绑的 Gradle 依赖项

弃用

使用 Java lambda 作为任务操作

当使用 Java lambda 实现任务操作时,Gradle 无法跟踪实现,并且任务永远不会是最新的或从构建缓存提供服务。由于添加这样的任务操作很容易,因此现在不推荐使用由 Java lambda 实现的任务操作。有关如何解决该问题的更多详细信息,请参阅验证问题。

不推荐依赖 equals 进行最新检查

当任务输入带有注释@Input并且不是 Gradle 直接理解的类型(例如String)时,Gradle 使用输入的序列化形式进行最新检查和构建缓存键。从历史上看,Gradle 还会加载上次执行的序列化值,然后将equals()其与当前值进行比较以进行最新检查。这样做很容易出错,无法与构建缓存一起使用,并且会影响性​​能,因此已被弃用。不要@Input在 Gradle 不能直接理解的类型上使用,而是@Nested相应地使用和注释类型的属性。

从 7.0 及更早版本升级

潜在的重大变化

更新默认工具集成版本

  • JaCoCo 已更新至0.8.7

org.gradle.util包现在是公共 API

正式地,该org.gradle.util包不是公共 API 的一部分。但是,因为这个包名称不包含单词internal,许多 Gradle 插件已经将其视为一个。 Gradle 7.1 解决了这种情况并将包标记为公共。无意暴露的类要么被弃用,要么被删除,具体取决于它们的外部使用情况。

以下类现已被正式认可为公共 API:
  • GradleVersion

  • Path

  • Configurable

以下类在外部插件中具有已知的用法,现在已弃用并在 Gradle 8.0 中设置为删除:
  • VersionNumber

  • TextUtil

  • WrapUtil

  • RelativePathUtil

  • DistributionLocator

  • SingleMessageLogger

  • ConfigureUtil

ConfigureUtil正在被移除而无需更换。ConfigureUtil按照我们的示例,插件可以避免使用。

以下类仅具有内部用途,已从包org.gradle.util中移出org.gradle.util.internal
  • Resources

  • RedirectStdOutAndErr

  • Swapper

  • StdInSwapper

  • IncubationLogger

  • RedirectStdIn

  • MultithreadedTestRule

  • DisconnectableInputStream

  • BulkReadInputStream

  • MockExecutor

  • FailsWithMessage

  • FailsWithMessageExtension

  • TreeVisitor

  • AntUtil

  • JarUtil

最后一组类没有外部或内部用途,因此被删除:
  • DiffUtil

  • NoopChangeListener

  • EnumWithClassBody

  • AlwaysTrue

  • ReflectionEqualsMatcher

  • DynamicDelegate

  • IncubationLogger

  • NoOpChangeListener

  • DeferredUtil

  • ChangeListener

源集扩展的返回类型已更改

以下源集是通过具有自定义类型的扩展提供的:

“惯用的”DSL 声明是向后兼容的:

sourceSets {
    main {
        groovy {
            // ...
        }
    }
}

但是,groovy 块的返回类型已更改为扩展类型。这意味着以下代码片段在 Gradle 7.1 中不再有效:

 sourceSets {
     main {
         GroovySourceSet sourceSet = groovy {
             // ...
         }
     }
 }

启动脚本需要 bash shell

用于启动 Gradle 的命令、Gradle 包装器以及application插件生成的脚本现在需要bashshell。

弃用

不推荐使用具有 Provider 类型的属性的约定映射

约定映射是一项内部功能,已被Provider API取代。将约定映射与提供程序 API 混合时,可能会发生意外行为。当任务、扩展或其他域对象中的属性使用提供者 API 的约定映射时,Gradle 会发出弃用警告。

要解决此问题,需要将为任务、扩展或域对象配置约定映射的插件更改为仅使用提供程序 API。

设置自定义构建布局

命令行选项:

  • -c--settings-file用于指定自定义设置文件位置

  • -b--build-file用于指定自定义构建文件位置

已被弃用。

已弃用在GradleBuild任务中使用buildFile 属性设置自定义构建文件 。

请使用dir 属性来指定嵌套构建的根目录。或者,考虑使用GradleBuild任务的推荐替代方案之一, 如 避免使用 GradleBuild 任务类型部分中的建议。

使用StartParameter方法 setBuildFile(File)setSettingsFile(File)设置自定义构建布局 以及对应的 getter getBuildFile()getSettingsFile() 已被弃用。

请使用设置和构建文件的标准位置:

  • 设置文件位于构建的根目录中

  • 每个子项目根目录下的构建文件

对于使用自定义设置或构建文件来建模不同行为(类似于 Maven 配置文件)的用例,请考虑使用带有条件逻辑的系统属性。例如,在设置或构建文件中给出一段代码:

if (System.getProperty("profile") == "custom") {
    println("custom profile")
} else {
    println("default profile")
}

您可以将profile系统属性传递给 Gradle,用于gradle -Dprofile=custom执行配置文件分支中的代码custom

Substitution.with 替换为 Substitution.using

使用方法的依赖替换with已被弃用,并替换为using也允许链接的方法。例如,依赖替换规则substitute(project(':a')).with(project(':b'))应替换为 substitute(project(':a')).using(project(':b')).例如,通过链接,您可以添加替换的原因,如下所示:substitute(project(':a')).using(project(':b')).because("a reason")

JavaExec 任务中不推荐使用的属性

compile任务中已弃用的属性

非层次化的项目布局

Gradle 7.1 弃用了子项目位于项目根目录之外的项目布局。然而,根据社区反馈,我们决定在 Gradle 7.4 中回滚并删除弃用内容。因此,Settings.includeFlat()方法仅在 Gradle 7.1、7.2 和 7.3 中被弃用。

已弃用的Upload任务

Gradle 过go有两种发布工件的方式。现在,情况已经清除,所有构建都应该使用该maven-publish插件。旧发布方式的最后一个工件是Upload已弃用并计划在 Gradle 8.0 中删除的任务。现有客户端应迁移到该maven-publish插件

已弃用的约定

约定的概念已经过时并被扩展所取代。为了在 Gradle API 中反映这一点,现在不推荐使用以下元素:

约定的内部用法也已清理(请参阅下面已弃用的项目)。

如果插件作者复制了我们内部所做的更改,他们就会迁移到扩展。这里有些例子:

已弃用内部插件配置的消耗

一些核心 Gradle 插件声明了插件本身使用的配置,并不意味着直接由另一个子项目发布或使用。 Gradle 并没有明确禁止这一点。 Gradle 7.1 不赞成使用这些配置,这将在 Gradle 8.0 中成为错误。

以下插件配置已被弃用以供使用:

插入 不推荐使用的配置

codenarc

codenarc

pmd

pmd

checkstyle

checkstyle

antlr

antlr

jacoco

jacocoAnt,jacocoAgent

scala

zinc

war

providedCompile,providedRuntime

如果您的用例需要在另一个项目中使用上述任何配置,请创建一个从内部扩展的单独的可用配置。例如:

plugins {
    id("codenarc")
}
configurations {
    codenarc {
        // because currently this is consumable until Gradle 8.0 and can clash with the configuration below depending on the attributes set
        canBeConsumed = false
    }
    codenarcConsumable {
        extendsFrom(codenarc)
        canBeConsumed = true
        canBeResolved = false
        // the attributes below make this configuration consumable by a `java-library` project using `implementation` configuration
        attributes {
            attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
            attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.LIBRARY))
            attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, LibraryElements.JAR))
            attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
            attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment, TargetJvmEnvironment.STANDARD_JVM));
        }
    }
}

已弃用的自定义源集接口

以下源集接口现已弃用并计划在 Gradle 8.0 中删除:

客户端应该使用其插件特定的配置来配置源:

例如,以下是如何从插件配置 groovy 源:

GroovySourceDirectorySet groovySources = sourceSet.getExtensions().getByType(GroovySourceDirectorySet.class);
groovySources.setSrcDirs(Arrays.asList("sources/groovy"));

注册工件转换扩展ArtifactTransform

当 Gradle 首次引入工件转换时,它使用基类ArtifactTransform来实现它们。 Gradle 5.3 引入了用于实现工件转换的接口TransformAction,取代了以前的类ArtifactTransform并解决了各种缺点。使用注册方法DependencyHandler.registerTransform(Action)ArtifactTransform被弃用。迁移您的工件转换以使用TransformActionDependencyHandler.registerTransform (Class, Action)代替。有关实施的更多信息,请参阅用户手册TransformAction