将您的构建从 Gradle 5.x 升级到 6.0
本章提供了将 Gradle 5.x 构建迁移到 Gradle 6.0 所需的信息。要从 Gradle 4.x 迁移,请先完成4.x 至 5.0 指南。
我们建议所有用户执行以下步骤
-
尝试运行
gradle help --scan
并查看生成的构建扫描的弃用视图。这样您就可以看到适用于您构建的任何弃用警告。
或者,您可以运行
gradle help --warning-mode=all
以在控制台中查看弃用信息,尽管它可能不会报告太多详细信息。 -
更新您的插件。
一些插件会因这个新版本的 Gradle 而中断,例如因为它们使用了已删除或更改的内部 API。在上一步中,当插件尝试使用 API 的已弃用部分时,将通过发出弃用警告来帮助您识别潜在问题。
-
运行
gradle wrapper --gradle-version 6.0
以将项目更新到 6.0。 -
尝试运行项目并使用故障排除指南调试任何错误。
从 5.6 及更早版本升级
弃用
不再应该使用 compile
和 runtime
配置来声明依赖项
自 Gradle 3.4 起,不鼓励在 Java 生态系统插件中使用 compile
和 runtime
配置。
这些配置用于编译和运行 main
源集中的代码。其他源集创建类似的配置(例如 testCompile
和 testRuntime
用于 test
源集),也不应使用。应使用 implementation
、api
、compileOnly
和 runtimeOnly
配置来声明依赖项,使用 compileClasspath
和 runtimeClasspath
配置来解析依赖项。请参阅 这些配置的关系。
旧版发布系统已弃用,并被 *-publish
插件取代
uploadArchives
任务和 maven
插件已弃用。
用户应使用 Gradle 发布系统,方法是使用 maven-publish
或 ivy-publish
插件进行迁移。自 Gradle 4.8 起,这些插件一直很稳定。
发布系统也是确保发布 Gradle 模块元数据 的唯一途径。
任务问题会发出弃用警告
当 Gradle 检测到任务定义存在问题(例如输入或输出定义不正确)时,它将在控制台上显示以下消息
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org.cn/6.0/userguide/command_line_interface.html#sec:command_line_warnings
无论使用何种命令行开关,弃用警告都会显示在 构建扫描 中的每次构建中。
当使用 --warning-mode all
执行构建时,将显示各个警告
> Task :myTask
Property 'inputDirectory' is declared without normalization specified. Properties of cacheable work must declare their normalization via @PathSensitive, @Classpath or @CompileClasspath. Defaulting to PathSensitivity.ABSOLUTE. This behavior is scheduled to be removed in Gradle 7.0.
Property 'outputFile' is not annotated with an input or output annotation. This behavior is scheduled to be removed in Gradle 7.0.
如果您拥有相关任务的代码,则可以通过 按照建议 来修复它们。您还可以使用 --stacktrace
来查看每个警告在代码中的来源。
否则,您需要向相关任务或插件的维护者报告问题。
增量任务的旧 API,IncrementalTaskInputs
,已弃用
在 Gradle 5.4 中,我们引入了一个用于实现增量任务的新 API:InputChanges。基于 IncrementalTaskInputs
的旧 API 已弃用。
StartParameter
中的向上搜索相关 API 已弃用
在 Gradle 5.0 中,我们移除了 --no-search-upward
CLI 参数。
StartParameter
中的相关 API(如 isSearchUpwards()
)现已弃用。
API BuildListener.buildStarted
和 Gradle.buildStarted
已弃用
由于在构建开始后永远不会调用回调,因此这些方法当前无法按预期工作。
为了避免混淆,这些方法已弃用。
Copy
或存档任务的隐式重复策略已弃用
默认情况下,存档任务 Tar
和 Zip
允许在创建的存档中存在针对同一路径的多个条目。这可能导致“非常无效的 zip 文件,可能触发 zip 炸弹检测”。
为了防止意外发生这种情况,在创建存档时遇到重复项现在会产生弃用消息,并且从 Gradle 7.0 开始构建将失败。
Copy
任务也会愉快地将具有相同相对路径的多个源复制到目标目录。此行为也已弃用。
如果您想允许重复项,可以明确指定
task archive(type: Zip) {
duplicatesStrategy = DuplicatesStrategy.INCLUDE // allow duplicates
...
}
在没有设置文件的情况下执行 Gradle 已弃用
Gradle 构建由当前或父目录中的 settings.gradle[.kts]
文件定义。如果没有设置文件,则 Gradle 构建未定义,并且会发出弃用警告。
在 Gradle 7.0 中,Gradle 只允许您使用未定义的构建调用 init
任务或诊断命令行标志(例如 --version
)。
在已评估的项目上调用 Project.afterEvaluate
已弃用
项目评估完成后,Gradle 将忽略所有传递给 Project#afterEvaluate
的配置并发出弃用警告。此场景将在 Gradle 7.0 中成为错误。
潜在重大更改
不再支持 Android Gradle 插件 3.3 及更低版本
Gradle 6.0 支持 Android Gradle 插件版本 3.4 及更高版本。
不再支持 Build 扫描插件 2.x
对于 Gradle 6,必须使用 Develocity 插件替换 Build 扫描插件的使用。这也需要更改插件的应用方式。请参阅 https://gradle.com/help/gradle-6-build-scan-plugin 以了解更多信息。
捆绑 Gradle 依赖项的更新
-
Groovy 已更新至 Groovy 2.5.8。
-
Kotlin 已更新至 Kotlin 1.3.50。
-
Ant 已更新至 Ant 1.10.7。
默认集成版本的更新
-
Checkstyle 已更新至 Checkstyle 8.24。
-
CodeNarc 已更新至 CodeNarc 1.4。
-
PMD 已更新至 PMD 6.17.0。
-
JaCoCo 已更新至 0.8.5。由 Evgeny Mandrikov 提供
复合构建中构建和任务名称的更改
以前,Gradle 使用根项目的名称作为包含构建的构建名称。现在,使用构建的根目录名称,并且如果不同,则不考虑根项目名称。如果通过设置文件包含构建,则可以指定构建的不同名称。
includeBuild("some-other-build") {
name = "another-name"
}
以前的行为存在问题,因为它导致在构建期间的不同时间使用不同的名称。
buildSrc 现在保留为项目和子项目构建名称
以前,Gradle 不会阻止将名称“buildSrc”用于多项目构建的子项目或作为包含构建的名称。现在,不允许这样做。名称“buildSrc”现在保留用于构建额外构建逻辑的传统 buildSrc 项目。
此更改不会影响 buildSrc 的典型用法。只有当您的设置文件指定 include("buildSrc")
或 includeBuild("buildSrc")
时,您才会受到影响。
Scala Zinc 编译器
Zinc 编译器已升级到 1.3.0 版本。Gradle 不再支持针对 Scala 2.9 进行构建。
Gradle 支持的最低 Zinc 编译器版本为 1.2.0,测试过的最高版本为 1.3.0。
为了更轻松地选择 Zinc 编译器的版本,您现在可以配置 zincVersion
属性
scala {
zincVersion = "1.2.1"
}
请删除您已添加到 zinc
配置中的任何显式依赖项,并改用此属性。如果您尝试使用 com.typesafe.zinc:zinc
依赖项,Gradle 将切换到新的 Zinc 实现。
本地构建缓存始终是目录缓存
过去,可以使用任何构建缓存实现作为 local
缓存。现在不允许这样做,因为本地缓存必须始终是 DirectoryBuildCache
。
对 BuildCacheConfiguration.local(Class)
的调用,如果类型不是 DirectoryBuildCache
,则构建将失败。使用 DirectoryBuildCache
类型调用这些方法将产生弃用警告。
改用 getLocal()
和 local(Action)
。
现在,无法打包或解包缓存结果将导致构建失败
过去,当 Gradle 在打包缓存任务的结果时遇到问题时,Gradle 会忽略该问题并继续运行构建。
在遇到损坏的缓存工件时,Gradle 会移除已解包的所有内容,并重新执行任务以确保构建有机会成功。
虽然此行为旨在使构建成功,但这产生了隐藏问题的副作用,并导致缓存性能下降。
在 Gradle 6.0 中,打包和解包错误都会导致构建失败,以便更容易发现这些问题。
buildSrc 项目自动使用构建缓存配置
以前,要对 buildSrc 构建使用构建缓存,需要在 buildSrc 构建中复制构建缓存配置。现在,它会自动使用顶级设置脚本定义的构建缓存配置。
始终发布 Gradle 模块元数据
Gradle 模块元数据在 Gradle 5.3 中正式推出,旨在解决多年来困扰依赖项管理的许多问题,特别是(但不仅限于)Java 生态系统中的问题。
在 Gradle 6.0 中,默认启用 Gradle 模块元数据。
这意味着,如果你使用 Gradle 发布库并使用 maven-publish 或 ivy-publish 插件,则 Gradle 模块元数据文件始终发布除了传统元数据之外。
传统元数据文件将包含一个标记,以便 Gradle 知道还有其他元数据要使用。
Gradle 模块元数据有更严格的验证
发布 Gradle 模块元数据时,会验证以下规则
-
变体名称必须唯一
-
每个变体都必须至少有一个属性
-
两个变体不能具有完全相同的属性和功能
-
如果存在依赖项,则所有变体中至少有一个必须携带版本信息。
这些内容也在规范中进行了说明。
默认情况下,不再针对没有元数据的工件查询 Maven 或 Ivy 存储库
如果 Gradle 无法在 repositories { }
部分中定义的存储库中找到模块的元数据文件(.pom
或 ivy.xml
),它现在会假定该模块不存在于该存储库中。
对于动态版本,相应模块的 maven-metadata.xml
需要存在于 Maven 存储库中。
以前,Gradle 还会查找默认工件(.jar
)。使用多个存储库时,这种行为通常会导致大量不必要的请求,从而减慢构建速度。
你可以通过添加 artifact()
元数据源,选择加入所选存储库的旧行为。
更改 pom packaging
属性不再更改工件扩展名
以前,如果 pom 打包不是 jar、ejb、bundle 或 maven-plugin,则在发布期间会更改发布到 Maven 存储库的主工件的扩展名,以匹配 pom 打包。
此行为导致 Gradle 模块元数据损坏,并且由于处理不同的打包类型,因此难以理解。
构建作者可以在创建工件时更改工件名称,以获得与以前相同的结果——例如,通过明确设置 jar.archiveExtension.set(pomPackaging)
。
为 Java 库发布的 ivy.xml
包含更多信息
在 ivy-publish
插件中进行了一些修复,以生成更正确的 ivy.xml
元数据。
因此,ivy.xml
文件的内部结构已更改。runtime
配置现在包含更多信息,这对应于 Java 库的 runtimeElements 变体。default
配置应产生与以前相同的结果。
总体而言,建议用户从 ivy.xml
迁移到新的 Gradle 模块元数据格式。
来自 buildSrc
的类不再对设置脚本可见
以前,buildSrc 项目是在应用项目的设置脚本之前构建的,并且其类在脚本中可见。现在,buildSrc 是在设置脚本之后构建的,并且其类对它不可见。buildSrc 类仍然对项目构建脚本和脚本插件可见。
可以通过 声明外部依赖项 从设置脚本中使用自定义逻辑。
设置脚本中的 pluginManagement
块现在已隔离
以前,设置脚本中的任何 pluginManagement {}
块都是在脚本的正常执行过程中执行的。
现在,它们以类似于 buildscript {}
或 plugins {}
的方式更早执行。这意味着此类块中的代码无法引用脚本中其他地方声明的任何内容。
进行此更改是为了在解决设置脚本本身的插件时也可以应用 pluginManagement
配置。
在设置脚本中加载的插件和类对项目脚本和 buildSrc
可见
以前,使用 buildscript {}
添加到设置脚本中的任何类在脚本外部不可见。现在,它们对所有项目构建脚本可见。
它们还对 buildSrc
构建脚本及其设置脚本可见。
进行此更改是为了使应用于设置脚本的插件可以为整个构建提供逻辑。
插件验证更改
-
validateTaskProperties
任务现在已弃用,请改用validatePlugins
。新名称更好地反映了它还验证工件转换参数和其他非属性定义这一事实。 -
ValidateTaskProperties
类型已被ValidatePlugins
替换。 -
setClasses()
方法现已删除。请改用getClasses().setFrom()
。 -
setClasspath()
方法也已删除。请改用getClasspath().setFrom()
。 -
现在默认启用 failOnWarning 选项。
-
以下任务验证错误现在在运行时导致构建失败,并针对 ValidatePlugins 提升为错误
-
任务属性使用任务不允许的属性注释,例如
@InputArtifact
。
-
使用 embedded-kotlin
插件现在需要一个存储库
就像使用 kotlin-dsl
插件一样,如果您应用 embedded-kotlin
插件,现在需要声明一个可以找到 Kotlin 依赖项的存储库。
plugins {
`embedded-kotlin`
}
repositories {
mavenCentral()
}
Kotlin DSL IDE 支持现在需要 Kotlin IntelliJ 插件 >= 1.3.50
对于早于 1.3.50 的 Kotlin IntelliJ 插件版本,当 Gradle JVM 设置为与 Project SDK 中的版本不同的版本时,Kotlin DSL 脚本将被错误地突出显示。只需将 IDE 插件升级到 >= 1.3.50 版本,即可恢复正确的 Kotlin DSL 脚本突出显示行为。
Kotlin DSL 脚本基本类型不再扩展 Project
、Settings
或 Gradle
在以前的版本中,Kotlin DSL 脚本被编译为实现三个核心 Gradle 配置接口之一的类,以便隐式地向脚本公开其 API。org.gradle.api.Project
用于项目脚本,org.gradle.api.initialization.Settings
用于设置脚本,org.gradle.api.invocation.Gradle
用于 init 脚本。
让脚本实例实现它应该配置的模型对象的 Gradle 核心接口很方便,因为它使模型对象 API 可以立即在脚本的主体中使用,但它也是一个谎言,可能会导致各种问题,只要脚本本身被用作模型对象,项目脚本不是一个合适的 Project
实例,仅仅因为它实现了核心 Project
接口,设置和 init 脚本也是如此。
在 6.0 中,所有 Kotlin DSL 脚本都将编译为实现新引入的 org.gradle.kotlin.dsl.KotlinScript
接口的类,并且相应的模型对象现在在脚本的主体中作为隐式接收器可用。换句话说,项目脚本的行为就像脚本的主体被包含在 with(project) { … }
块中,设置脚本的行为就像脚本的主体被包含在 with(settings) { … }
块中,而初始化脚本的行为就像脚本的主体被包含在 with(gradle) { … }
块中。这意味着相应的模型对象也作为脚本主体中的属性可用,项目脚本的 project
属性、设置脚本的 settings
属性和初始化脚本的 gradle
属性。
作为更改的一部分,SettingsScriptApi
接口不再由设置脚本实现,InitScriptApi
接口不再由初始化脚本实现。它们应该替换为相应的模型对象接口 Settings
和 Gradle
。
Javadoc 和 Groovydoc 默认情况下不包含时间戳
生成文档中的时间戳实际用途非常有限,但它们使得无法进行可重复的文档构建。因此,Javadoc
和 Groovydoc
任务现在被配置为默认情况下不再包含时间戳。
Checkstyle 忽略用户提供的“config_loc”属性
运行 Checkstyle 时,Gradle 始终使用 configDirectory
作为“config_loc”的值。
新的 Tooling API 进度事件
在 Gradle 6.0 中,我们引入了一个新的进度事件 (org.gradle.tooling.events.test.TestOutputEvent) 来公开测试执行的输出。此新事件打破了使用 StartEvent
-FinishEvent
对来表示进度的惯例。TaskOutputEvent
是一个简单的 ProgressEvent
。
任务容器行为的更改
任务容器上的以下弃用方法现在会导致错误
-
TaskContainer.add()
-
TaskContainer.addAll()
-
TaskContainer.remove()
-
TaskContainer.removeAll()
-
TaskContainer.retainAll()
-
TaskContainer.clear()
-
TaskContainer.iterator().remove()
此外,以下弃用功能现在会导致错误
-
替换已经实现的任务。
-
用不兼容的类型替换已注册(未实现)的任务。兼容类型是相同类型或已注册类型的子类型。
-
替换从未注册的任务。
DefaultTask
和 ProjectLayout
上的方法已用 ObjectFactory
替换
使用 ObjectFactory.fileProperty()
替换以下现已删除的方法
-
DefaultTask.newInputFile()
-
DefaultTask.newOutputFile()
-
ProjectLayout.fileProperty()
使用 ObjectFactory.directoryProperty()
替换以下现已删除的方法
-
DefaultTask.newInputDirectory()
-
DefaultTask.newOutputDirectory()
-
ProjectLayout.directoryProperty()
注释 @Nullable
已删除
org.gradle.api.Nullable
注释类型已删除。改用 JSR-305 中的 javax.annotation.Nullable
。
FindBugs 插件已删除
已弃用的 FindBugs 插件已删除。作为替代,你可以从 Gradle 插件门户 使用 SpotBugs 插件。
JDepend 插件已删除
已弃用的 JDepend 插件已删除。在 Gradle 插件门户 上有许多社区提供的代码和架构分析插件。
OSGI 插件已删除
已弃用的 OSGI 插件已删除。在 Gradle 插件门户 上有许多社区提供的 OSGI 插件。
announce 和 build-announcements 插件已删除
已弃用的 announce 和 build-announcements 插件已删除。在 Gradle 插件门户 上有许多社区提供的用于发送通知的插件。
Compare Gradle Builds 插件已移除
已弃用的 Compare Gradle Builds 插件已移除。请使用 构建扫描 进行构建分析和比较。
Play 插件已移除
已弃用的 Play 插件已移除。插件门户中提供了外部替代项,即 Play Framework 插件。
方法 AbstractCompile.compile()
方法已移除
抽象方法 compile()
不再由 AbstractCompile
声明。
扩展 AbstractCompile
的任务可以实现自己的 @TaskAction
方法,方法名由自己选择。
它们还可以自由地添加使用 @TaskAction
注释的方法,其中包含 InputChanges
参数,而无需实现无参数的方法。
其他已弃用的行为和 API
-
org.gradle.util.internal.GUtil.savePropertiesNoDateComment
已移除。此内部方法没有公开的替代项。 -
已弃用的类
org.gradle.api.tasks.compile.CompilerArgumentProvider
已移除。请改用 org.gradle.process.CommandLineArgumentProvider。 -
已弃用的类
org.gradle.api.ConventionProperty
已移除。请使用 Provider 替代约定属性。 -
已弃用的类
org.gradle.reporting.DurationFormatter
已移除。 -
返回
TaskInputs
的桥接方法org.gradle.api.tasks.TaskInputs.property(String name, @Nullable Object value)
已移除。使用该方法的插件必须使用 Gradle 4.3 编译才能在 Gradle 6.0 上运行。 -
以下 setter 已从
JacocoReportBase
中移除-
executionData - 请改用
getExecutionData().setFrom()
。 -
sourceDirectories - 请改用
getSourceDirectories().setFrom()
。 -
classDirectories - 请改用
getClassDirectories().setFrom()
。 -
additionalClassDirs - 请改用
getAdditionalClassDirs().setFrom()
。 -
additionalSourceDirs - 改用
getAdditionalSourceDirs().setFrom()
。
-
-
JacocoTaskExtension
上的append
属性已移除。append
现在始终配置为 Jacoco 代理的 true。 -
JacocoPlugin
上的configureDefaultOutputPathForJacocoMerge
方法已移除。该方法从未打算公开。 -
ear 插件的 部署描述符文件名 中不再允许文件路径。改用简单名称,如
application.xml
。 -
org.gradle.testfixtures.ProjectBuilder
构造函数已移除。请改用ProjectBuilder.builder()
。 -
启用 增量 Groovy 编译 时,现在会因源根配置错误或为 Groovy 启用 Java 注解而导致构建失败。在这些情况下,禁用增量 Groovy 编译。
-
ComponentSelectionRule
不再可以注入元数据或 ivy 描述符。改用ComponentSelection
参数 上的方法。 -
现在,声明 增量任务 而未声明输出是一个错误。声明文件输出或改用 TaskOutputs.upToDateWhen()。
-
getEffectiveAnnotationProcessorPath()
方法已从JavaCompile
和ScalaCompile
任务中移除。 -
在任务开始执行后更改类型为
Property<T>
的任务属性的值现在会导致错误。 -
isLegacyLayout()
方法已从SourceSetOutput
中移除。 -
TaskInputs.getProperties()
返回的地图现在不可修改。尝试修改它将导致抛出UnsupportedOperationException
。 -
5.6 中引入的孵化 功能解析 API 中有细微的更改,它还允许基于变体名称进行变体选择
从 5.5 及更早版本升级
弃用
在任务开始执行后更改 ConfigurableFileCollection
任务属性的内容
当任务属性的类型为 ConfigurableFileCollection
时,由属性引用的文件集合将忽略任务开始执行后对集合内容所做的更改。这有以下两个好处。首先,这可以防止在任务执行期间意外更改属性值,从而导致 Gradle 最新检查和构建缓存查找使用与任务操作所用值不同的值。其次,这可以提高性能,因为 Gradle 可以计算一次值并缓存结果。
这将在 Gradle 6.0 中成为错误。
创建 SignOperation
实例
直接创建 SignOperation
实例现在已弃用。相反,应使用 SigningExtension
的方法来创建这些实例。
这将在 Gradle 6.0 中成为错误。
方法 WorkerExecutor.submit()
已弃用
WorkerExecutor.submit()
方法现已弃用。现在应使用新的 noIsolation()
、classLoaderIsolation()
和 processIsolation()
方法来提交工作。有关如何使用这些方法的更多信息,请参见 Worker API 部分。
WorkerExecutor.submit()
将在 Gradle 8.0 中移除。
潜在的重大更改
任务依赖关系将被用于值是 Property
的任务 @Input
属性
以前,任务依赖关系将被忽略,用于类型为 Property<T>
的任务 @Input
属性。现在它们被认可,因此可以将任务输出属性附加到任务 @Input
属性。
这可能会在任务依赖关系图中引入意外循环,其中输出属性的值被映射为生成输入属性的值。
使用不表示任务输出的文件Provider
声明任务依赖项
以前,可以向Task.dependsOn()
传递不表示任务输出的Provider<File>
、Provider<RegularFile>
或Provider<Directory>
实例。这些提供程序将被静默忽略。
现在这是一个错误,因为 Gradle 不知道如何构建不是任务输出的文件。
请注意,仍然可以向Task.dependsOn()
传递返回文件并表示任务输出的Provider
,例如myTask.dependsOn(jar.archiveFile)
或myTask.dependsOn(taskProvider.flatMap { it.outputDirectory })
,当Provider
是任务的带注释的@OutputFile
或@OutputDirectory
属性时。
将Property
值设置为null
使用属性约定
以前,调用Property.set(null)
始终会将属性值重置为“未定义”。现在,将使用使用convention()
方法与属性关联的约定来确定属性的值。
对publishing.publications
和publishing.repositories
的名称进行增强验证
存储库和发布名称用于构建用于发布的任务名称。可以提供一个导致无效任务名称的名称。发布和存储库的名称现在限制为[A-Za-z0-9_\\-.]+
。
受限的 Worker API 类加载器和进程类路径
Gradle 现在阻止内部依赖项(如 Guava)泄漏到 Worker API 操作使用的类路径中。这修复了一个问题,其中一个工作需要使用 Gradle 内部也使用的依赖项。
在以前的版本中,可以依赖这些泄漏的类。依赖此行为的插件现在将失败。要修复插件,工作应在其类路径中明确包含所有必需的依赖项。
配置副本具有唯一名称
以前,配置的所有副本始终具有名称 <OriginConfigurationName>Copy
。现在,在创建多个副本时,每个副本都将具有唯一名称,方法是从第二个副本开始添加索引。(例如 CompileOnlyCopy2
)
更改了 Eclipse 的类路径筛选
Gradle 5.6 不再在 Eclipse 模型中提供自定义类路径属性。相反,它为 Eclipse 测试源 提供属性。此更改需要 Buildship 3.1.1 或更高版本。
嵌入式 Kotlin 已升级至 1.3.41
现在使用 kotlin-dsl
插件创作的 Gradle Kotlin DSL 脚本和 Gradle 插件将使用 Kotlin 1.3.41 编译。
现在,最低受支持的 Kotlin Gradle 插件版本为 1.2.31。以前为 1.2.21。
自动功能冲突解决
在功能冲突的情况下,Gradle 的以前版本会自动选择具有最高功能版本的那个模块。从 5.6 开始,这是一个可选择的行为,可以使用以下方式激活
configurations.all {
resolutionStrategy.capabilitiesResolution.all { selectHighestVersion() }
}
有关更多选项,请参阅 文档的功能部分。
文件删除操作不遵循符号链接目录
当 Gradle 由于各种原因必须删除任务的输出文件时,它不会遵循符号链接目录。符号链接本身将被删除,但链接目录的内容将保持不变。
已禁用 JavaExec 中的调试参数解析
Gradle 5.6 引入了新的 DSL 元素(JavaForkOptions.debugOptions(Action<JavaDebugOptions>)
),用于为分叉 Java 进程配置调试属性。由于此更改,Gradle 不再解析与调试相关的 JVM 参数。因此,如果向进程指定 -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
或 -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
参数,则 JavaForkOptions.getDebu()
不再返回 true
。
Scala 2.9 和 Zinc 编译器
Gradle 不再支持使用 Scala 2.9 构建应用程序。
从 5.4 及更早版本升级
弃用
Play
内置 Play 插件 已弃用,并将由插件门户中提供的新的 Play Framework 插件 取代。
潜在的重大更改
在冲突时,用户提供的 Eclipse 项目名称可能会被忽略
通过 EclipseProject.setName(…)
配置的项目名称在所有情况下都受到 Gradle 和 Buildship 的尊重,即使名称导致冲突和导入/同步错误也是如此。
如果 Gradle 中的这些名称与 Eclipse 工作空间中的其他项目名称冲突,Gradle 现在可以对这些名称进行重复数据删除。这可能会导致具有用户指定名称的项目的 Eclipse 项目名称不同。
需要即将推出的 Buildship 3.1.1 版本才能利用此行为。
由 Christian Fränkel 贡献
嵌入式 Ant 版本已升级至 1.9.14
Gradle 分发的 Ant 版本已从 1.9.13 升级至 1.9.14。
类型 DependencyHandler
现在静态地公开 ExtensionAware
这会影响使用 ExtensionAware
扩展成员的 Kotlin DSL 构建脚本,例如 dependencies {}
块内的 extra
属性访问器。这些成员的接收器不再是封闭的 Project
实例,而是 dependencies
对象本身,即最内部的 ExtensionAware
符合接收器。为了在 dependencies {}
内处理 Project
额外属性,接收器必须明确限定,即 project.extra
,而不是仅 extra
。受影响的扩展还包括 the<T>()
和 configure<T>(T.() → Unit)
。
改进了对依赖排除的处理
在某些复杂的依赖关系图中,Gradle 的早期版本在存在大量排除项时可能会产生错误的结果或随机的依赖关系顺序。为了缓解此问题,计算排除项的算法已被重写。在某些罕见情况下,由于正确性更改,这可能会导致解决中出现一些差异。
改进了工作进程的类路径分离
使用 PROCESS
隔离时,Worker API 启动的工作守护进程的系统类路径已减少到 Gradle 基础设施的最小集合。用户代码仍被隔离到一个单独的类加载器中,以将其与 Gradle 运行时隔离。对于使用 Worker API 的任务来说,这应该是一个透明的更改,但 Gradle 的早期版本在工作进程中混合了用户代码和 Gradle 内部组件。依赖于 java.class.path
系统属性等内容的工作操作可能会受到影响,因为 java.class.path
现在仅表示 Gradle 内部组件的类路径。
从 5.3 及更早版本升级
弃用
使用自定义本地构建缓存实现
现在弃用为本地构建缓存使用自定义构建缓存实现。将来唯一允许的类型将是 DirectoryBuildCache
。在将自定义构建缓存实现用作远程构建缓存方面,支持没有发生变化。
潜在的重大更改
通过 googleApis()
配置 Google 托管库时使用 HTTPS
可通过 JavaScriptRepositoriesExtension#GOOGLE_APIS_REPO_URL
访问的 Google 托管库 URL 已更改为使用 HTTPS 协议。此更改还影响通过 googleApis()
配置的 Ivy 存储库。
从 5.2 及更早版本升级
潜在的重大更改
平台解析中的错误修复
Gradle 5.0 至 5.2.1(包括)存在一个错误,其中强制平台可能会包含依赖项而不是约束。每当 POM 文件同时定义依赖项和“约束”(通过 <dependencyManagement>
)并且您使用 enforcedPlatform
时,就会发生这种情况。Gradle 5.3 修复了此错误,这意味着如果您依赖于此错误行为,则解析结果可能会有所不同。同样,Gradle 5.3 将不再尝试为 platform
和 enforcedPlatform
依赖项下载 jar(因为它们只应引入约束)。
自动目标 JVM 版本
如果你应用任何 Java 插件,Gradle 现在会尽力选择与正在编译的模块的目标兼容性匹配的依赖项。在实践中,这意味着如果你有为 Java 8 构建的模块 A 和为 Java 8 构建的模块 B,那么就没有变化。但是,如果 B 是为 Java 9+ 构建的,那么它不再是二进制兼容的,Gradle 会抱怨类似于以下内容的错误消息
Unable to find a matching variant of project :producer:
- Variant 'apiElements' capability test:producer:unspecified:
- Provides org.gradle.dependency.bundling 'external'
- Required org.gradle.jvm.version '8' and found incompatible value '9'.
- Required org.gradle.usage 'java-api' and found value 'java-api-jars'.
- Variant 'runtimeElements' capability test:producer:unspecified:
- Provides org.gradle.dependency.bundling 'external'
- Required org.gradle.jvm.version '8' and found incompatible value '9'.
- Required org.gradle.usage 'java-api' and found value 'java-runtime-jars'.
一般来说,这表明你的项目配置错误,并且你的依赖项不兼容。但是,在某些情况下,你仍然可能希望这样做,例如,当你的模块的类只有子集实际上需要 Java 9 依赖项,并且不打算在早期版本中使用时。Java 通常不鼓励你这样做(你应该拆分你的模块),但是如果你遇到此问题,可以通过在使用者端禁用此新行为来解决
java {
disableAutoTargetJvm()
}
Maven/Ivy 互操作性中的错误修复,带依赖项替换
如果你有一个 Maven 依赖项指向一个 Ivy 依赖项,其中default
配置依赖项与compile
+ runtime
+ master
依赖项不匹配并且该 Ivy 依赖项已被替换(使用resolutionStrategy.force
、resolutionStrategy.eachDependency
或resolutionStrategy.dependencySubstitution
),那么此修复将影响你。Gradle 的旧行为(在 5.0 之前)仍然存在,而不是被改进的 pom 支持引入的更改所取代。
删除操作在 Windows 上正确处理符号链接
在存在连接点和符号链接的情况下,Gradle 不再忽略 Windows 上clean
任务、所有Delete
任务和project.delete {}
操作的followSymlink
选项。
发布其他工件时的修复
在以前的 Gradle 版本中,在项目级别注册的其他工件不会由 maven-publish
或 ivy-publish
发布,除非它们也作为工件添加到发布配置中。
在 Gradle 5.3 中,这些工件现在可以正确地进行记录和发布。
这意味着同时在项目和发布(Ivy 或 Maven)中注册的工件将导致发布失败,因为它将创建重复的条目。解决方法是从发布配置中删除这些工件。
从 5.0 及更早版本升级
弃用
请按照 API 链接了解如何处理这些弃用(如果此处未提供其他信息)
-
org.gradle.plugin.devel.tasks.ValidateTaskProperties
上classes
和classpath
的设置器(已删除) -
对于诸如
ConfigurableFileCollection
之类的惰性属性,不应有设置器。改用setFrom
。例如,
validateTaskProperties.getClasses().setFrom(fileCollection) validateTaskProperties.getClasspath().setFrom(fileCollection)
潜在的重大更改
以下更改以前未被弃用
签名 API 更改
Sign
任务的输入和输出文件现在分别通过 Signature.getToSign()
和 Signature.getFile()
进行跟踪。
集合属性默认为空集合
在 Gradle 5.0 中,使用 ObjectFactory
创建的集合属性实例将没有定义的值,要求插件作者显式设置初始值。这被证明很尴尬且容易出错,因此 ObjectFactory
现在返回以空集合作为初始值的实例。
Worker API:不再可以设置 worker 的工作目录
由于 JDK 11 不再支持更改正在运行的进程的工作目录,因此现在禁止通过其 fork 选项设置 worker 的工作目录。所有 worker 现在都使用相同的工作目录以启用重用。请改用文件和目录作为参数传递。请参阅 Worker API 文档 中的示例。
对本机链接任务的更改
为了扩展我们的惯用 Provider API 实践,org.gradle.nativeplatform.tasks.LinkSharedLibrary
中的安装名称属性受到此更改的影响。
-
getInstallName()
已更改为返回Property
。 -
setInstallName(String)
已删除。改用Property.set()
。
传递参数给 Windows 资源编译器
为了扩展我们的惯用 提供程序 API 实践,WindowsResourceCompile
任务已转换为使用提供程序 API。
传递其他编译器参数现在遵循与 CppCompile
和其他任务相同的模式。
复制的配置不再与原件共享 beforeResolve
操作列表
beforeResolve
操作列表不再在复制的配置和原件之间共享。相反,复制的配置在复制时收到 beforeResolve
操作的副本。在复制之后添加的任何 beforeResolve
操作(到任一配置)都不会在原件和副本之间共享。这可能会破坏依赖于以前行为的插件。
对孵化 POM 自定义类型的更改
-
MavenPomDeveloper.properties
的类型已从Property<Map<String, String>>
更改为MapProperty<String, String>
。 -
MavenPomContributor.properties
的类型已从Property<Map<String, String>>
更改为MapProperty<String, String>
。
更改以指定本机项目的操作系统
本机组件上的孵化 operatingSystems
属性已替换为 targetMachines 属性。
存档任务的更改(Zip
、Jar
、War
、Ear
、Tar
)
扩展 AbstractArchiveTask
的任务的行为更改
AbstractArchiveTask
有几个使用 提供程序 API 的新属性。扩展这些类型并覆盖基类中的方法的插件可能不再以相同的方式运行。在内部,AbstractArchiveTask
优先使用新属性,并且 getArchiveName()
等方法是新属性的表象。
如果您的插件/构建仅使用这些类型(并且不扩展它们),则没有任何更改。