将构建从 Gradle 7.x 升级到 8.0
本章提供将 Gradle 7.x 构建迁移到 Gradle 8.0 所需的信息。要从 Gradle 6.x 或更早版本迁移,请先完成旧版迁移指南。
我们建议所有用户执行以下步骤:
-
尝试运行
gradle help --scan
并查看生成的构建扫描的弃用视图。这样您就可以看到适用于您的构建的任何弃用警告。
或者,您可以运行
gradle help --warning-mode=all
以在控制台中查看弃用信息,尽管它可能不会报告那么多详细信息。 -
更新您的插件。
一些插件将与这个新版本的 Gradle 兼容,例如因为它们使用已删除或更改的内部 API。当插件尝试使用 API 的已弃用部分时,上一步将通过发出弃用警告来帮助您识别潜在问题。
-
运行
gradle wrapper --gradle-version 8.7
将项目更新到8.7。 -
尝试运行该项目并使用故障排除指南调试任何错误。
从 7.6 及更早版本升级
警告现在是错误
finalizedBy
使用,mustRunAfter
或引用包含的构建中的任务shouldRunAfter
现在,使用以下任何方法引用包含的构建中包含的任务都会导致执行时间错误:
-
finalizedBy
-
mustRunAfter
-
shouldRunAfter
从资源创建 TAR 树,无需备份文件
不再支持从没有后备文件的资源创建 TAR 树。相反,请将资源转换为文件并project.tarTree()
在该文件上使用。有关详细信息,请参阅来自不带备份文件的资源的 TAR 树。
使用无效的 Java 工具链规范
不再支持使用无效的 Java 工具链规范。通过确保在所有工具链规范上设置语言版本,可以避免相关的构建错误。请参阅用户手册了解更多信息。
在没有配置存储库的情况下使用自动工具链下载
不再支持在不明确提供要使用的存储库的情况下自动下载工具链。请参阅用户手册了解更多信息。
设置测试框架选项后更改测试框架现在会出现错误
当为 Java、Groovy 和 Scala 项目配置内置测试任务时,Gradle 不再允许您Test
在配置选项后更改任务使用的测试框架。这已被弃用,因为它在某些情况下会默默地丢弃配置。
以下代码示例现在会产生错误:
test {
options {
}
useJUnitPlatform()
}
相反,您可以:
-
在配置选项之前设置测试框架
-
迁移到JVM 测试套件插件
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
旧版ArtifactTransform
API 已被删除。有关更多信息,请参阅注册工件转换扩展ArtifactTransform
。
旧版 IncrementalTaskInputs API
旧版IncrementalTaskInputs
API 已被删除。有关详细信息,请参阅IncrementalTaskInputs 类型已弃用。此更改还会影响 Kotlin Gradle 插件和 Android Gradle 插件。对于 Gradle 8.0,您应该使用 Kotlin Gradle Plugin 1.6.10 或更高版本,以及 Android Gradle Plugin 7.3.0 with android.experimental.legacyTransform.forceNonIncremental=true
property 或更高版本。
旧版 AntlrSourceVirtualDirectory API
旧版AntlrSourceVirtualDirectory
API 已被删除。此更改会影响antlr
插件。在 Gradle 8.0 及更高版本中,请改用AntlrSourceDirectorySet
源集扩展。
Jvm插件助手
不需要 a 的类configureDocumentationVariantWithArtifact
的已弃用方法已被删除。这是一个内部 API,但可能已被插件访问。相反,向该方法的重载版本提供 a 。JvmPluginsHelper
FileResolver
FileResolver
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
, 和属性已被删除。请改用和属性。enabled
Report
outputLocation
required
testResultDirs
任务类型的已弃用属性TestReport
已被删除。而是使用该testResults
属性。
JacocoMerge 任务已删除
已弃用的JacocoMerge
任务类型已被删除。该任务也可以使用相同的功能JacocoReport
。
JavaExec API 清理
main
任务类型的已弃用属性JavaExec
已被删除。而是使用该mainClass
属性。
AbstractExecTask API 清理
任务类型已弃用的execResult
getter 属性AbstractExecTask
已被删除。请改用executionResult
getter 属性。
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)
方法已被删除。请改用该方法。DependencySubstitution
Substitution
using(ComponentSelector)
AbstractArchiveTask API 清理
任务类型已弃用的、appendix
、archiveName
、archivePath
、baseName
、classifier
和destinationDir
属性已被删除。请改用、、、、、和属性。extension
version
AbstractArchiveTask
archiveAppendix
archiveFileName
archiveFile
archiveBaseName
archiveClassifier
destinationDirectory
archiveExtension
archiveVersion
IdeaModule API 清理
已弃用的类型testSourceDirs
和testResourceDirs
属性IdeaModule
已被删除。这会影响org.gradle.plugins.ide.idea.model.IdeaModule
类型,而不是org.gradle.tooling.model.idea.IdeaModule
类型。请改用testSources
和testResources
属性。
AbstractCompile API 弃用
之前已弃用destinationDir
的属性AbstractCompile
仍然已弃用,现在将在使用时发出弃用警告。现在计划在 Gradle 9.0 中删除它。而是使用该destinationDirectory
属性。
ResolvedComponentResult API 清理
getVariant
接口中已弃用的方法ResolvedComponentResult
已被删除。请改用该getVariants
方法。
代码质量插件 API 清理
、和任务类型的已弃用antBuilder
属性已被删除。请改用类型的属性。Checkstyle
CodeNarc
Pmd
Project
ant
使用 API 清理
该类型已弃用的公共字段JAVA_API_CLASSES
、JAVA_API_JARS
、JAVA_RUNTIME_CLASSES
和已被删除。这些值在内部类中可用,以便与以前发布的模块兼容,但不应用于任何新发布。JAVA_RUNTIME_JARS
JAVA_RUNTIME_RESOURCES
Usage
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#map
or返回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-opens
Gradle 工作线程的隐式内容
在 Gradle 8.0 之前,JDK9+ 上的 Gradle Worker 自动打开 JDK 模块java.base/java.util
并java.base/java.lang
通过传递--add-opens
CLI 参数。这使得在 Gradle Worker 中执行的代码能够在 JDK 内部执行深度反射,而不会发出警告或失败。工人不再使用这些隐含的论点。
这会影响所有内部 Gradle 工作人员,这些工作人员用于执行各种任务:
-
代码质量插件(Checkstyle、CodeNarc、Pmd)
-
Scala文档
-
反任务
-
JVM 编译器守护进程
新的警告和错误可能会出现在使用工作 API 对 JDK 内部进行深度反射的任何工具、扩展或插件中。
这些错误可以通过更新违规代码或依赖项来解决。更新可能包括:
-
代码质量工具
-
注释处理器
-
任何使用worker API的Gradle插件
有关由于此更改而可能出现的错误或警告输出的一些示例,请参阅删除--add-opens
测试工作人员的隐含内容。
SourceSet classesDirs 不再依赖于整个 SourceSet 作为任务依赖项
SourceSetOutput.classesDirs
在 Gradle 8.0 之前,包含不生成类文件的任务的任务依赖项。这意味着依赖于 的任务classesDirs
也将依赖于classes
、processResources
以及添加到 的任何其他任务依赖项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
任务取决于compileJava
、processResources
和classes
。现在,仅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 中是错误,并且会使构建失败。
变成错误的警告:
-
无法解析的输入文件集合。
-
无法读取的输入或输出文件或目录。请参阅声明包含不可读内容的输入或输出目录。
-
使用 a
java.io.File
作为@InputArtifact
工件变换的 。 -
使用未知实现的输入。请参阅无法使用未知实现的输入。
-
任务之间缺少依赖关系。请参阅任务之间的隐式依赖关系。
-
将文件转换为类路径,其中路径包含文件分隔符。
Gradle 不会忽略文件树的空目录@SkipWhenEmpty
以前,Gradle 用于检测注释的输入文件集合是否@SkipWhenEmpty
仅包含文件树,然后自动忽略目录。要忽略 Gradle 8.0 及更高版本中的目录,需要使用 显式注释 input 属性@IgnoreEmptyDirectories
。有关详细信息,请参阅文件树和空目录处理。
JavaVersion
Java 9 和 Java 10的格式已更改
的字符串格式JavaVersion
已更改以匹配官方 Java 版本控制。从Java 9开始,语言版本不能包含前缀1.
。这会影响任务和 的sourceCompatiblity
和targetCompatibility
属性的格式。从字符串解析 时,仍然支持旧格式。JavaCompile
JavaExtension
JavaVersion
摇篮7.6 |
摇篮8.0 |
|
|
|
|
|
|
|
|
预编译脚本插件默认使用严格的 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
includeBuild("nested")
includeBuild("nestedNested")
.
├── settings.gradle
└── nested
├── settings.gradle
└── nestedNested
└── settings.gradle
includeBuild("nested")
includeBuild("nestedNested")
在 Gradle 8.0 之前,您运行gradle :nestedNested:compileJava
.在 Gradle 8.0 中,调用更改为gradle :nested:nestedNested:compileJava
.
现在jst.ejb
使用插件添加会删除方面eclipse wtp
jst.utility
该eclipse wtp
插件将jst.utility
facet添加到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>
outputLocation
Provider<? 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-plugin
的validatePlugins
任务来验证正在开发的插件。
与过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
插件将
Jar、War和
Ear任务的
目标目录配置为BasePluginExtension#getLibsDirectory指定的目录
。在 Gradle 8.0 中,处理此配置。对于已经通过、、或其他 JVM 生态系统插件直接或间接应用该插件的项目,无需进行任何更改
。java-base
java-base
java
application
java-library
不应使用上传任务
该Upload
任务仍然已弃用,现在计划在 Gradle 9.0 中删除。尽管此类型仍然存在,但它不再起作用,并且在运行时会抛出异常。保留它只是为了避免破坏插件。请改用maven-publish
或插件中的任务ivy-publish
。
不再允许配置作为依赖项
不再允许将配置添加为dependencies
DSL 块中的依赖项,或以编程方式使用类DependencyHandler
的方法,并且将失败并出现异常。doAdd(Configuration, Object, Closure)
要复制此行为的许多方面,请改为使用extendsFrom(Configuration)
on 方法扩展配置Configuration
。
已弃用的消耗配置现在是非消耗配置
以下配置永远不会被使用:
-
antlr
创建的配置AntlrPlugin
-
zinc
创建的配置ScalaBasePlugin
-
创建的
providedCompile
和配置providedRuntime
WarPlugin
这些配置已被弃用,现在不再可供使用。尝试使用它们将导致错误。
相同的耗材配置现在是一个错误
如果项目具有多个共享相同属性和功能声明的可用配置,则在发布或解析为该项目的依赖项时,构建将会失败。这以前已被弃用。
该outgoingVariants
报告将对受影响的配置发出警告。
JVM 项目的基于工具链的任务
从 Gradle 8.0 开始,所有具有工具链支持的核心 Java 任务现在都无条件使用工具链。如果JavaBasePlugin
应用,则任务上工具属性的约定值由扩展上配置的工具链定义java
。如果没有显式配置工具链,则使用与运行 Gradle 的 JVM 对应的工具链。
同样,Groovy 和 Scala 插件中的任务也依赖于工具链来确定它们在哪个 JVM 上执行。
Scala 编译目标
通过上述工具链的更改,Scala 编译任务现在始终提供一个target
orrelease
参数。确切的参数和值取决于工具链的使用与否以及 Scala 版本。
有关详细信息,请参阅Scala 插件文档。
从 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 {
// ...
}
升级到 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>
依赖项声明。 -
您不能使用 a
Map
作为 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 及更早版本升级
IncrementalTaskInputs 类型已弃用
该IncrementalTaskInputs
类型用于实现增量任务,也就是说可以优化为在更改的输入的子集而不是整个输入上运行的任务。这种类型有许多缺点。特别是使用这种类型时,无法确定更改与哪个输入相关联。
您现在应该改用该InputChanges
类型。有关更多详细信息,请参阅用户指南中有关实施增量任务的部分。
潜在的重大变化
版本目录仅接受单个 TOML 导入文件
使用导入方法时仅接受单个文件from
。这意味着解析为多个文件的符号(例如,当传递多个文件时的Project.files(java.lang.Object…)方法)将导致构建失败。
更新默认工具集成版本
-
Checkstyle 已更新至Checkstyle 8.45.1。
-
JaCoCo 已更新至0.8.8。
插件生成的类路径文件eclipse
已更改
测试配置中定义的项目依赖项获取test=true
类路径属性。默认情况下,JVM 测试套件插件定义的所有源集和依赖项也被标记为测试代码。您现在可以通过插件 DSL 自定义测试源集和依赖项eclipse
:
eclipse {
classpath {
testSourceSets = [sourcesSets.test, sourceSets.myTestSourceSet]
testConfigurations = [configuration.myTestConfiguration]
}
}
或者,您可以调整或删除eclipse.classpath.file.whenMerged { }
块中的类路径属性。
使用 GPG 命令时,签名插件默认为gpg
而不是gpg2
使用 GPG 命令时签名插件的默认可执行文件从 更改gpg2
为gpg
。随着 GPG 2.x 变得稳定,并且发行版开始通过不链接可执行文件进行迁移,引发了这一变化gpg2
。
为了设置旧的默认值,可以在以下位置手动定义可执行文件gradle.properties
:
signing.gnupg.executable=gpg2
mustRunAfter
finalizedBy
依赖关系不再违反约束
在以前的 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
更新捆绑的 Gradle 依赖项
-
Groovy 已更新至Groovy 3.0.11。
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.lang
和java.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.exec
、Project.javaexec
和标准 Java 和 Groovy API 在配置时运行外部进程。在 Gradle 8.0 及更高版本中这将是一个错误。 Gradle 7.5 引入了配置缓存兼容的方法,通过基于提供者的 API或接口的自定义实现来执行和获取外部进程的输出ValueSource
。配置缓存章节提供了更多详细信息,可帮助迁移到新 API。
从 7.3 及更早版本升级
潜在的重大变化
更新默认工具集成版本
-
PMD 已更新至PMD 6.39.0。
弃用
采用OpenJDK工具链下载
从 AdoptOpenJDK 迁移到 Adoptium 后,在 Eclipse 基础下,不再可能从其端点下载 AdoptOpenJDK 版本。相反,会返回 Eclipse Temurin 或 IBM Semeru 构建。
当在工具链规范中指定 AdoptOpenJDK 供应商并且自动配置使用它时,Gradle 7.4+ 现在将发出弃用警告。如果必须使用AdoptOpenJDK,则应关闭自动下载。如果 Eclipse Temurin 或 IBM Semeru 构建适合您,请指定JvmVendorSpec.ADOPTIUM
或JvmVendorSpec.IBM
作为供应商,或不指定供应商。
文件树和空目录处理
在输入文件集合上使用时,Gradle 在确定输入为空时会跳过该任务。如果输入文件集合仅包含文件树,Gradle 会忽略目录进行空性检查。尽管在检查输入文件集合的更改时,Gradle 仅在存在注释时忽略目录。@SkipWhenEmpty
@IgnoreEmptyDirectories
@SkipWhenEmpty
Gradle 现在将忽略检查和一致确定更改的目录。在 Gradle 8.0 之前,Gradle 会检测注释的输入文件集合是否@SkipWhenEmpty
仅包含文件树,然后自动忽略目录。此外,Gradle 会发出弃用警告,告知用户 Gradle 8.0 中的行为将发生变化,并且输入属性应使用@IgnoreEmptyDirectories
.要忽略 Gradle 8.0 及更高版本中的目录,需要使用 .input 属性进行注释@IgnoreEmptyDirectories
。
最后,使用implied ,因此使用此注释时无需进行任何更改。通过运行时 API 注册输入目录时也是如此。@InputDirectory
@IgnoreEmptyDirectories
inputs.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 中删除。客户只需删除该呼叫即可。
从 7.4 版开始,Gradle 将隐式地将配置时使用的外部值视为配置缓存输入。
客户端还可以自由使用标准 Java API,例如System#getenv
读取环境变量、System#getProperty
读取系统属性以及 Gradle API,例如Project#property(String)
在Project#findProperty(String)
配置时读取 Gradle 属性。基于APIProvider
仍然是将外部值连接到任务输入以实现最大配置缓存重用的推荐方法。
ConfigurableReport#setDestination(org.gradle.api.provider.Provider<java.io.File>)
已被弃用
ConfigurableReport#setDestination(org.gradle.api.provider.Provider<java.io.File>)
现已弃用并计划在 Gradle 8.0 中删除。
任务执行监听器和事件
Gradle 配置缓存不支持直接访问实例的侦听器和事件Task
,Project
这允许 Gradle 并行执行任务并在配置缓存中存储最少量的数据。为了实现无论配置缓存是否启用都保持一致的 API,以下 API 已被弃用,并将在 Gradle 8.0 中被删除或出现错误:
-
接口任务执行监听器
-
接口任务动作监听器
-
通过Gradle.addListener()注册 TaskExecutionListener、TaskActionListener、TestListener、TestOutputListener
有关如何将这些用法迁移到配置缓存支持的 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 和 VersionCatalogBuilder 弃用
VersionCatalog和VersionCatalogBuilder中的一些方法现已弃用,并计划在 Gradle 8.0 中删除。具体替换可以在受影响方法的 JavaDoc 中找到。
libs.versions.toml
更改这些方法是为了提高文件和 API 类之间的一致性。
从 7.2 及更早版本升级
潜在的重大变化
更新捆绑的 Gradle 依赖项
-
Kotlin 已更新至Kotlin 1.5.31。
-
Groovy 已更新至Groovy 3.0.9。
-
Ant 已更新至Ant 1.10.11以修复CVE-2021-36373和CVE-2021-36374。
-
Commons compress 已更新至Commons-compress 1.21以修复CVE-2021-35515、CVE-2021-35516、CVE-2021-35517和CVE-2021-36090。
plugins
块中插件的应用顺序
块中插件的实际应用顺序plugins
不一致,并且取决于插件如何添加到类路径中。
现在,插件始终按照在plugins
块中声明的顺序应用,这在极少数情况下可能会改变现有构建的行为。
依赖解析中排除对替换依赖的影响
在此版本之前,无法从依赖关系图中排除依赖关系替换目标。这是由于在执行替换之前检查排除项而导致的。现在 Gradle 还将检查替换结果的排除情况。
Scala 中的工具链支持
在 Scala 中使用工具链时,-target
Scala 编译器的选项现在将自动设置。这意味着使用 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_OPTS
或GRADLE_OPTS
通过复杂的引号转义传递参数的 Gradle 构建可能会发生变化。如果您怀疑某些东西破坏了您的构建并且无法找到解决方案,请联系我们。
更新捆绑的 Gradle 依赖项
-
Groovy 已更新至Groovy 3.0.8。
-
Kotlin 已更新至Kotlin 1.5.21。
更新默认工具集成版本
-
PMD 已更新至PMD 6.36.0。
弃用
使用 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
源集扩展的返回类型已更改
以下源集是通过具有自定义类型的扩展提供的:
-
groovy
: GroovySourceDirectorySet -
antlr
: Antlr源目录集 -
scala
:Scala源目录集
“惯用的”DSL 声明是向后兼容的:
sourceSets {
main {
groovy {
// ...
}
}
}
但是,groovy 块的返回类型已更改为扩展类型。这意味着以下代码片段在 Gradle 7.1 中不再有效:
sourceSets {
main {
GroovySourceSet sourceSet = groovy {
// ...
}
}
}
启动脚本需要 bash shell
用于启动 Gradle 的命令、Gradle 包装器以及application
插件生成的脚本现在需要bash
shell。
弃用
不推荐使用具有 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 任务中不推荐使用的属性
-
JavaExec任务中的主要getter和 setter已被弃用。请改用mainClass属性。
compile
任务中已弃用的属性
-
JavaCompile.destinationDir 属性已被弃用。请改用JavaCompile.destinationDirectory 属性。
-
GroovyCompile.destinationDir 属性已被弃用。请改用GroovyCompile.destinationDirectory 属性。
-
ScalaCompile.destinationDir 属性已被弃用。请改用ScalaCompile.destinationDirectory 属性。
非层次化的项目布局
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 中反映这一点,现在不推荐使用以下元素:
-
org.gradle.api.internal.HasConvention
(已弃用)
约定的内部用法也已清理(请参阅下面已弃用的项目)。
如果插件作者复制了我们内部所做的更改,他们就会迁移到扩展。这里有些例子:
-
迁移插件配置:gradle/gradle#16900。
-
迁移自定义源集:gradle/gradle#17149。
已弃用内部插件配置的消耗
一些核心 Gradle 插件声明了插件本身使用的配置,并不意味着直接由另一个子项目发布或使用。 Gradle 并没有明确禁止这一点。 Gradle 7.1 不赞成使用这些配置,这将在 Gradle 8.0 中成为错误。
以下插件配置已被弃用以供使用:
插入 | 不推荐使用的配置 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果您的用例需要在另一个项目中使用上述任何配置,请创建一个从内部扩展的单独的可用配置。例如:
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 中删除:
-
org.gradle.api.plugins.antlr.AntlrSourceVirtualDirectory
(已删除)
客户端应该使用其插件特定的配置来配置源:
-
groovy
: GroovySourceDirectorySet -
antlr
: Antlr源目录集 -
scala
:Scala源目录集
例如,以下是如何从插件配置 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
被弃用。迁移您的工件转换以使用TransformAction
DependencyHandler.registerTransform (Class, Action)代替。有关实施的更多信息,请参阅用户手册TransformAction
。