将你的构建从 Gradle 4.x 升级到 5.0
本章提供将旧版本 Gradle 4.x 构建迁移到 Gradle 5.0 所需的信息。在大多数情况下,您需要应用从您要升级的版本之后的所有版本的更改。例如,如果您要从 Gradle 4.3 升级到 5.0,您还需要应用自 4.4、4.5 等直到 5.0 的更改。
如果您正在将 Gradle 用于 Android,则需要迁移到 Android Gradle 插件和 Android Studio 的 3.3 或更高版本。 |
面向所有用户
-
如果您尚未升级到最新的 4.10.x 版本,请阅读下面的 章节,以获取将项目升级到最新的 4.10.x 版本的帮助。我们建议升级到最新的 4.10.x 版本,以便在迁移到 5.0 之前获得最有用的警告和弃用信息。为了便于在出现潜在问题时进行故障排除,请避免同时升级 Gradle 和迁移到 Kotlin DSL。
-
尝试运行
gradle help --scan
并查看生成的构建扫描的 弃用视图。如果没有警告,则不会显示“弃用”选项卡。这样做是为了让您可以看到适用于您构建的任何弃用警告。如果您尝试直接升级到 Gradle 5.x,它将生成(可能不太明显的)错误。
或者,您可以运行
gradle help --warning-mode=all
以在控制台中查看弃用信息,但这可能不会报告太多详细信息。 -
更新您的插件。
某些插件会在此新版本的 Gradle 中崩溃,例如,因为它们使用了已删除或更改的内部 API。上一步将通过在插件尝试使用已弃用的 API 部分时发出弃用警告来帮助您识别潜在问题。
特别是,您需要使用至少 2.x 版本的 Shadow Plugin。
-
运行
gradle wrapper --gradle-version 5.0
以将项目更新到 5.0 -
如果您尚未迁移到 Java 8 或更高版本,请进行迁移。Gradle 4.x 需要 Java 7,而 Gradle 5 需要 Java 8 才能运行。
-
阅读 从 4.10 升级 章节并进行任何必要的更改。
-
尝试运行项目并使用 问题排查指南 调试任何错误。
此外,Gradle 还添加了几个重要的新功能和改进功能,您应该考虑在构建中使用这些功能
-
Maven Publish 和 Ivy Publish 插件 现在支持使用 Signing Plugin 进行数字签名。
-
在您的构建中使用原生 BOM 导入。
-
用于使工作单元并行运行的 Worker API。
-
用于 延迟创建和配置 task 的新 API,可以显著缩短构建的配置时间。
需要注意的其他可能破坏构建的显著更改包括
-
一项更改意味着您应该 配置现有的
wrapper
和init
task,而不是定义自己的 task。 -
Maven POM 排除项中隐式通配符的遵循,这可能会导致以前未排除的依赖项被排除。
-
命令行客户端、Gradle 守护程序和所有工作进程(包括编译器和测试执行器)的 默认内存设置 已大大减少。
-
几个代码质量插件的 默认版本 已更新。
-
Gradle 使用的几个 库版本 已升级。
从 4.10 及更早版本升级
如果您尚未升级到 4.10 版本,请跳至适用于您当前 Gradle 版本的章节,然后逐步升级到此处。然后,在从 Gradle 4.10 迁移到 5.0 时应用这些更改。
其他更改
-
不再需要
enableFeaturePreview('IMPROVED_POM_SUPPORT')
和enableFeaturePreview('STABLE_PUBLISHING')
标志。这些功能现在默认启用。 -
Gradle 现在为 Java 9 及更高版本捆绑了 JAXB。如果已设置,您可以从
org.gradle.jvmargs
中删除--add-modules java.xml.bind
选项。
潜在的破坏性更改
本节中的更改可能会破坏您的构建,但绝大多数更改已被弃用很长时间,并且很少有构建会受到其中大量更改的影响。我们强烈建议首先升级到 Gradle 4.10,以获取有关哪些弃用会影响您的构建的报告。
以下破坏性更改并非来自弃用,而是行为更改的结果
-
publishing {}
块的评估不再延迟到需要时,而是像任何其他块一样运行。如果您需要延迟评估,请使用afterEvaluate {}
。 -
Javadoc
和Groovydoc
task 现在在执行前删除文档的目标目录。添加此功能是为了删除上次 task 执行中的过时输出文件。 -
Java Library Distribution Plugin 现在基于 Java Library Plugin 而不是 Java Plugin。
虽然它应用了 Java Plugin,但其行为略有不同(例如,它添加了
api
配置)。因此,请确保检查升级后您的构建是否按预期运行。 -
CheckstyleReport
和FindBugsReport
上的html
属性现在返回CustomizableHtmlReport
实例,该实例更易于从 Java 和 Kotlin 等静态类型语言进行配置。 -
配置避免 API 已更新,以防止创建和配置从未使用过的 task。
-
命令行客户端、Gradle 守护程序和所有工作进程(包括编译器和测试执行器)的 默认内存设置 已大大减少。
-
几个代码质量插件的 默认版本 已更新。
-
Gradle 使用的几个 库版本 已升级。
以下破坏性更改将作为 Gradle 4.10 的弃用警告出现
- 常规
-
-
<<
用于 task 定义不再有效。换句话说,您不能使用语法task myTask << { … }
。请改用 Task.doLast() 方法,如下所示
task myTask { doLast { ... } }
-
您不能再在域对象名称(例如项目和 task 名称)中使用以下任何字符:<空格>
/ \ : < > " ? * |
。您也不应使用.
作为前导或尾随字符。
-
- 运行 Gradle 和构建环境
-
-
如前所述,Gradle 无法再在 Java 7 上运行。但是,您仍然可以使用 forked compilation and testing 来构建和测试适用于 Java 6 及更高版本的软件。
-
-Dtest.single
命令行选项已删除 — 请改用 测试过滤。 -
-Dtest.debug
命令行选项已删除 — 请改用--debug-jvm
选项。 -
-u
/--no-search-upward
命令行选项已删除 — 请确保您的所有构建都有 settings.gradle 文件。 -
--recompile-scripts
命令行选项已删除。 -
除非嵌套的构建具有 settings.gradle 文件,否则您不能再在另一个 Gradle 构建的子目录中嵌套 Gradle 构建。
-
DirectoryBuildCache.setTargetSizeInMB(long)
方法已删除 — 请改用 DirectoryBuildCache.removeUnusedEntriesAfterDays。 -
org.gradle.readLoggingConfigFile
系统属性不再执行任何操作 — 请更新受影响的测试以使用您的java.util.logging
设置。
-
- 处理文件
-
-
您不能再使用
as
关键字或asType()
方法将FileCollection
对象强制转换为其他类型。 -
您不能再将
null
作为 CopySpec.from(Object, Action) 的配置操作传递。 -
为了更好地与 Kotlin DSL 兼容,CopySpec.duplicatesStrategy 不再可为空。属性 setter 不再接受
null
作为将属性重置回其默认值的方式。请改用DuplicatesStrategy.INHERIT
。 -
FileCollection.stopExecutionIfEmpty()
方法已删除 — 请改用FileCollection
task 属性上的 @SkipWhenEmpty 注解。 -
FileCollection.add()
方法已删除 — 请使用 Project.files() 和 Project.fileTree() 创建可配置的文件集合/文件树,并通过 ConfigurableFileCollection.from() 将其添加到其中。 -
SimpleFileCollection
已删除 — 请改用 Project.files(Object…)。 -
不要让您自己的类扩展
AbstractFileCollection
— 请改用 Project.files() 方法。此问题可能会表现为缺少getBuildDependencies()
方法。
-
- Java 构建
-
-
CompileOptions.bootClasspath
属性已删除 — 请改用 CompileOptions.bootstrapClasspath。 -
您不能再将
-source-path
用作通用编译器参数 — 请改用 CompileOptions.sourcepath。 -
您不能再将
-processorpath
用作通用编译器参数 — 请改用 CompileOptions.annotationProcessorPath。 -
Gradle 将不再自动应用编译 classpath 上的注释处理器 — 请改用 CompileOptions.annotationProcessorPath。
-
testClassesDir
属性已从 Test task 中删除 — 请改用 testClassesDirs。 -
classesDir
属性已从 JDepend task 和 SourceSetOutput 中删除。请改用 JDepend.classesDirs 和 SourceSetOutput.classesDirs 属性。 -
JavaLibrary(PublishArtifact, DependencySet)
构造函数已删除 — Shadow Plugin 使用了此构造函数,因此请确保您升级到该插件的至少 2.x 版本。 -
JavaBasePlugin.configureForSourceSet()
方法已删除。 -
您不能再创建自己的 JavaPluginConvention、ApplicationPluginConvention、WarPluginConvention、EarPluginConvention、BasePluginConvention 和 ProjectReportsPluginConvention 实例。
-
Maven
Plugin 过去用于发布过时的 Maven 2 元数据格式。这已更改,它现在将发布 Maven 3 元数据,就像Maven Publish
Plugin 一样。随着 Maven 2 支持的删除,配置唯一快照行为的方法也已删除。Maven 3 仅支持唯一快照,因此我们决定删除它们。
-
- Task 和属性
-
-
以下与 延迟属性 相关的旧类和方法已删除 — 请使用 ObjectFactory.property() 创建
Property
实例-
PropertyState
-
DirectoryVar
-
RegularFileVar
-
ProjectLayout.newDirectoryVar()
-
ProjectLayout.newFileVar()
-
Project.property(Class)
-
Script.property(Class)
-
ProviderFactory.property(Class)
-
-
使用 task 配置避免 API 配置和注册的 Task 对可以从配置操作调用的其他方法有更多限制。
-
内部
@Option
和@OptionValues
注解 — 包org.gradle.api.internal.tasks.options
— 已删除。请改用公共 @Option 和 @OptionValues 注解。 -
Task.deleteAllActions()
方法已删除,没有替代方法。 -
Task.dependsOnTaskDidWork()
方法已删除 — 请改用 声明的输入和输出。 -
以下
TaskInternal
的属性和方法已删除 — 请使用 task 依赖项、task 规则、可重用的实用程序方法或 Worker API 来代替直接执行 task。-
execute()
-
executer
-
getValidators()
-
addValidator()
-
-
TaskInputs.file(Object) 方法不能再使用解析为单个常规文件以外的任何内容的参数调用。
-
TaskInputs.dir(Object) 方法不能再使用解析为单个目录以外的任何内容的参数调用。
-
您不能再通过 TaskInputs 和 TaskOutputs 注册无效的输入和输出。
-
TaskDestroyables.file()
和TaskDestroyables.files()
方法已删除 — 请改用 TaskDestroyables.register()。 -
SimpleWorkResult
已删除 — 请使用 WorkResult.didWork。 -
覆盖 4.8 中弃用 的内置 task 现在会生成错误。
尝试替换内置 task 将生成类似于以下的错误
> Cannot add task 'wrapper' as a task with that name already exists.
-
- Scala 和 Play
-
-
不再支持 Play 2.2 — 请升级您正在使用的 Play 版本。
-
ScalaDocOptions.styleSheet
属性已删除 — Scala 2.11.8 及更高版本中的 Scaladoc Ant task 不再支持此属性。
-
- Kotlin DSL
-
-
工件配置访问器现在具有
NamedDomainObjectProvider<Configuration>
类型,而不是Configuration
-
PluginAware.apply<T>(to)
已重命名为PluginAware.applyTo<T>(target)
。
这两个更改都可能导致脚本编译错误。有关更多信息以及如何修复因上述更改而损坏的构建,请参阅 Gradle Kotlin DSL 发行说明。
-
- 其他
-
-
ConfigurableReport.setDestination(Object)
方法已删除 — 请改用 ConfigurableReport.setDestination(File)。 -
Signature.setFile(File)
方法已删除 — Gradle 不支持更改生成的签名的输出文件。 -
只读
Signature.toSignArtifact
属性已删除 — 它永远不应成为公共 API 的一部分。 -
@DeferredConfigurable
注解已删除。 -
方法
isDeferredConfigurable()
已从ExtensionSchema
中删除。 -
IdeaPlugin.performPostEvaluationActions()
和EclipsePlugin.performPostEvaluationActions()
已删除。 -
方法
BroadcastingCollectionEventRegister.getAddAction()
已删除,没有替代方法。 -
内部
org.gradle.util
包不再默认导入。理想情况下,您不应使用此包中的类,但作为快速修复,您可以为这些类向构建脚本添加显式导入。
-
gradlePluginPortal()
仓库 默认情况下不再查找没有 POM 的 JAR。 -
Tooling API 无法再连接到使用低于 Gradle 2.6 的 Gradle 版本的构建。通过 TestKit 运行的构建也适用。
-
Gradle 5.0 需要最低 Tooling API 客户端版本 3.0。旧版本的客户端库无法再使用 Gradle 5.0 运行构建。
-
IdeaModule Tooling API 模型元素包含检索资源和测试资源的方法,因此这些元素已从
IdeaModule.getSourceDirs()
和IdeaModule.getTestSourceDirs()
的结果中删除。 -
在以前的 Gradle 版本中,子类可以访问
SourceTask
中的source
字段。现在情况并非如此,因为source
字段现在声明为private
。 -
在 Worker API 中,worker 的工作目录不能再设置。
-
与 依赖项和版本约束 相关的行为更改可能会影响少数用户。
-
DefaultTask 上的属性工厂方法 发生了一些更改,可能会影响自定义 task 的创建。
-
从 4.9 及更早版本升级
如果您尚未升级到 4.9 版本,请跳至适用于您当前 Gradle 版本的章节,然后逐步升级到此处。然后,在升级到 Gradle 4.10 时应用这些更改。
已弃用的类、方法和属性
请按照 API 链接了解如何处理这些弃用(如果此处未提供其他信息)
-
TaskContainer.add()
和TaskContainer.addAll()
— 请改用 TaskContainer.create() 或 TaskContainer.register()
潜在的破坏性更改
-
Kotlin DSL 中发生了一些潜在的破坏性更改 — 请参阅 该项目的发行说明的破坏性更改部分。
-
您不能再将任何 Project.beforeEvaluate() 或 Project.afterEvaluate() 方法与延迟 task 配置一起使用,例如在 TaskContainer.register() 块内。
-
PluginUnderTestMetadata 和 GeneratePluginDescriptors — Java Gradle Plugin Development Plugin 使用的类 — 已更新为使用 Provider API。
请使用 Property.set() 方法修改其值,而不是使用标准属性赋值语法,除非您在 Groovy 构建脚本中执行此操作。标准属性赋值在该情况下仍然有效。
从 4.8 及更早版本升级
潜在的破坏性更改
-
您不能再将 GPath 语法与 tasks.withType() 一起使用。
请改用 Groovy 的 spread 运算符。例如,您可以用
tasks.withType(JavaCompile)*.name
替换tasks.withType(JavaCompile).name
。
从 4.7 及更早版本升级
-
配置现有的
wrapper
和init
task,而不是定义自己的 task -
如果您当前正在为此使用插件或自定义解决方案,请考虑迁移到内置的 依赖项锁定机制
潜在的破坏性更改
-
如果找不到指定的 init 脚本,构建现在将失败。
-
TaskContainer.remove()
现在实际上删除了给定的 task — 某些插件可能意外地依赖了旧的行为。 -
Kotlin DSL 现在遵循 JSR-305 包注解。
这将导致一些根据 JSR-305 注解的类型被视为可为空,而之前它们被视为不可为空。这可能会导致构建脚本中出现编译错误。有关详细信息,请参阅 相关的 Kotlin DSL 发行说明。
-
除非控制台同时连接到标准输出和标准错误,否则错误消息现在将定向到标准错误而不是标准输出。如果您是从早期版本的 Gradle 升级,请忽略此更改。
从 4.6 及更早版本升级
潜在的破坏性变更
-
Gradle 现在将按照惯例,在根项目的 config/checkstyle 目录中查找 Checkstyle 配置文件。
子项目中的 Checkstyle 配置文件(旧的默认位置)将被忽略,除非您通过 checkstyle.configDir 或 checkstyle.config 显式配置其路径。
-
Gradle 的 纯文本控制台输出 的结构已更改,这可能会破坏抓取该输出的工具。
-
许多与编译、链接和安装相关的原生任务的 API 已发生重大更改。
-
[Kotlin DSL] 用于访问 Gradle 构建属性(例如在 gradle.properties 中定义的属性)的委托属性现在必须显式类型化。
-
[Kotlin DSL] 在嵌套作用域内声明
plugins {}
代码块现在会抛出异常。 -
[Kotlin DSL] 现在只允许一个
pluginManagement {}
代码块。 -
org.gradle.api.artifacts.cache.*
接口提供的缓存控制 DSL 不再可用。 -
getEnabledDirectoryReportDestinations()
、getEnabledFileReportDestinations()
和getEnabledReportNames()
已全部从org.gradle.api.reporting.ReportContainer
中移除。 -
StartParameter.projectProperties 和 StartParameter.systemPropertiesArgs 现在返回不可变映射。
从 4.5 及更早版本升级
弃用
-
您不应将注解处理器放在编译类路径上,也不应使用
-processorpath
编译器参数声明它们。应将它们添加到
annotationProcessor
配置中。如果您不想要任何处理,但您的编译类路径意外地包含了一个处理器(例如,作为您依赖的库的一部分),请使用-proc:none
编译器参数来忽略它。
潜在的破坏性变更
-
Java 插件现在为每个源集添加一个
sourceSetAnnotationProcessor
配置,如果其中任何一个与您现有的配置匹配,则可能会中断。我们建议您删除冲突的配置声明。 -
StartParameter.taskOutputCacheEnabled
属性已被 StartParameter.setBuildCacheEnabled(boolean) 替换。 -
Visual Studio 集成现在仅 为构建中的所有组件配置单个解决方案。
-
Gradle 已将 HttpClient 从 4.4.1 替换为 4.5.5 版本。
-
Gradle 现在捆绑了
kotlin-stdlib-jdk8
工件,而不是kotlin-stdlib-jre8
。这可能会影响您的构建。请参阅 Kotlin 文档 以获取更多详细信息。
从 4.4 及更早版本升级
-
确保您有一个 settings.gradle 文件:它可以避免性能损失,并允许您设置根项目的名称。
-
Gradle 现在忽略包含构建(组合构建)的构建缓存配置,而是对所有构建使用根构建的配置。
潜在的破坏性变更
-
移除了两个重载的
ValidateTaskProperties.setOutputFile()
方法。当从构建脚本访问任务时,它们会被自动生成的 setter 替换,但从插件和构建脚本之外的其他代码访问则不会。 -
Maven Publish Plugin 现在生成更完整的 maven-metadata.xml 文件,包括维护
<snapshotVersion>
元素的列表。某些旧版本的 Maven 可能无法使用此元数据。 -
Depend
任务类型已被移除。 -
Project.file(Object) 不再规范化不区分大小写的文件系统上的文件路径的大小写。现在,在这种情况下,它会忽略大小写,并且不会触及文件系统。
-
ListProperty 不再扩展 Property。
从 4.3 及更早版本升级
潜在的破坏性变更
-
AbstractTestTask 现在由非 JVM 测试任务以及 Test 扩展。插件应注意配置所有
AbstractTestTask
类型的任务,因为这种情况。 -
EclipseClasspath.defaultOutputDir 的默认输出位置已从
$projectDir
/bin 更改为$projectDir
/bin/default。 -
已移除弃用的
InstallExecutable.setDestinationDir(Provider)
— 使用 InstallExecutable.installDirectory 代替。 -
已移除弃用的
InstallExecutable.setExecutable(Provider)
— 使用 InstallExecutable.executableFile 代替。 -
Gradle 将不再优先选择在路径上找到的 Visual Studio 版本,而不是其他位置。现在它是最后的选择。
您可以通过指定您想要的 Visual Studio 版本的安装目录来绕过工具链发现,通过 VisualCpp.setInstallDir(Object)。
-
pluginManagement.repositories
现在是 RepositoryHandler 类型,而不是已移除的PluginRepositoriesSpec
。 -
依赖项解析期间的 5xx HTTP 错误现在将在构建中触发异常。
-
嵌入式 Apache Ant 已从 1.9.6 升级到 1.9.9。
-
Gradle 使用的几个第三方库已升级,以修复安全问题。
从 4.2 及更早版本升级
-
plugins {}
代码块现在可以在子项目中使用,也可以用于 buildSrc 目录中的插件。
其他弃用
-
您不应再通过 Tooling API 运行 2.6 之前的 Gradle 版本。
-
您不应再通过比 3.0 更旧版本的 Tooling API 运行任何版本的 Gradle。
-
您不应再链式调用 TaskInputs.property(String,Object) 和 TaskInputs.properties(Map) 方法。
潜在的破坏性变更
-
DefaultTask.newOutputDirectory() 现在返回
DirectoryProperty
而不是DirectoryVar
。 -
DefaultTask.newOutputFile() 现在返回
RegularFileProperty
而不是RegularFileVar
。 -
DefaultTask.newInputFile() 现在返回
RegularFileProperty
而不是RegularFileVar
。 -
ProjectLayout.buildDirectory 现在返回
DirectoryProperty
而不是DirectoryVar
。 -
AbstractNativeCompileTask.compilerArgs 现在是
ListProperty<String>
类型,而不是List<String>
。 -
AbstractNativeCompileTask.objectFileDir 现在是
DirectoryProperty
类型,而不是File
。 -
AbstractLinkTask.linkerArgs 现在是
ListProperty<String>
类型,而不是List<String>
。 -
TaskDestroyables.getFiles()
不再是公共 API 的一部分。 -
依赖项的重叠版本范围现在会导致 Gradle 选择满足所有声明范围的版本。
例如,如果找到对
some-module
的依赖项,其版本范围为[3,6]
,并且也传递性地找到版本范围为[4,8]
的依赖项,则 Gradle 现在选择版本 6 而不是 8。之前的行为是选择 8。 -
使用
@OutputFiles
或@OutputDirectories
注解标记的Iterable
属性中元素的顺序现在很重要。如果顺序更改,则该属性不再被视为最新。首选使用带有
@OutputFile
/@OutputDirectory
注解的单独属性,或使用带有@OutputFiles
/@OutputDirectories
的Map
属性代替。 -
当存在另一个可以检查的仓库时,Gradle 将不再忽略来自仓库的依赖项解析错误。而是依赖项解析将失败。这导致关于解析结果的更确定性行为。
从 4.1 及更早版本升级
潜在的破坏性变更
-
TaskFilePropertyBuilder 和 TaskOutputFilePropertyBuilder 上的
withPathSensitivity()
方法已被移除。 -
捆绑的
bndlib
已从 3.2.0 升级到 3.4.0。 -
FindBugs 插件不再呈现其分析的进度信息。如果您以任何方式依赖该输出,您可以使用 FindBugs.showProgress 启用它。
从 4.0 升级
-
考虑使用新的 Worker API 以便在您的构建中启用并行运行的工作单元。
详细变更
[5.0] 默认内存设置已更改
命令行客户端现在以 64MB 的堆内存启动,而不是 1GB。这可能会影响直接在客户端 VM 中使用 --no-daemon
模式运行的构建。我们不鼓励使用 --no-daemon
,但如果您必须使用它,您可以使用 GRADLE_OPTS
环境变量增加可用内存。
Gradle 守护进程现在以 512MB 的堆内存启动,而不是 1GB。大型项目可能必须使用 org.gradle.jvmargs
属性增加此设置。
所有 worker,包括编译器和测试执行器,现在都以 512MB 的堆内存启动。之前的默认值是物理内存的 1/4。大型项目可能必须在相关任务上增加此设置,例如 JavaCompile
或 Test
。
[5.0] 代码质量插件的新默认工具版本
以下代码质量插件的默认工具版本已更新
-
Checkstyle 插件 现在默认使用 8.12 而不是 6.19。
-
CodeNarc 插件 现在默认使用 1.2.1 而不是 1.1。
-
PMD 插件 现在默认使用 6.8.0 而不是 5.6.1。
此外,默认规则集已从现在已弃用的
java-basic
更改为category/java/errorprone.xml
。我们建议显式配置规则集。
[5.0] 库升级
Gradle 使用的几个库已升级
-
Groovy 已从 2.4.15 升级到 2.5.4。
-
Ant 已从 1.9.11 升级到 1.9.13。
-
用于访问 S3 支持的 Maven/Ivy 仓库的 AWS SDK 已从 1.11.267 升级到 1.11.407。
-
OSGi 插件使用的 BND 库已从 3.4.0 升级到 4.0.0。
-
用于访问 Google Cloud Storage 支持的 Maven/Ivy 仓库的 Google Cloud Storage JSON API 客户端库已从 v1-rev116-1.23.0 升级到 v1-rev136-1.25.0。
-
Ivy 已从 2.2.0 升级到 2.3.0。
-
Test
任务使用的 JUnit Platform 库已从 1.0.3 升级到 1.3.1。 -
用于访问 Maven 仓库的 Maven Wagon 库已从 2.4 升级到 3.0.0。
-
SLF4J 已从 1.7.16 升级到 1.7.25。
[5.0] 改进了对依赖项和版本约束的支持
在 Gradle 4.x 发布流中,为依赖项解析引擎添加了新的 @Incubating
功能。这些功能包括复杂的版本约束(prefer
、strictly
、reject
)、依赖项约束和 platform
依赖项。
如果您一直在使用 IMPROVED_POM_SUPPORT
功能预览,尝试约束或 prefer、reject 和其他特定版本指示,请务必仔细查看您的依赖项解析结果。
[5.0] BOM 导入
Gradle 现在提供对导入物料清单 (BOM) 文件的支持,这些文件实际上是 POM 文件,使用 <dependencyManagement>
部分来控制直接和传递依赖项的版本。您只需将 POM 声明为 platform
依赖项即可。
以下示例从声明的 Spring Boot BOM 中选择 gson
和 dom4j
依赖项的版本
dependencies { // import a BOM implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') // define dependencies without versions implementation 'com.google.code.gson:gson' implementation 'dom4j:dom4j' }
[5.0] 使用 POM 时编译和运行时依赖项的分离
自 Gradle 1.0 以来,运行时作用域的依赖项已包含在 Java 编译类路径中,这有一些缺点
-
编译类路径比需要的要大得多,减慢了编译速度。
-
编译类路径包含不影响编译的运行时作用域文件,当这些文件更改时会导致不必要的重新编译。
通过这种新行为,Java 和 Java Library 插件都遵循 编译和运行时作用域的分离。这意味着编译类路径仅包含编译作用域的依赖项,而运行时类路径也添加了运行时作用域的依赖项。如果您使用 Gradle 开发和发布 Java 库,其中 api
和 implementation
依赖项之间的分离反映在已发布的作用域中,则这尤其有用。
[5.0] DefaultTask
上属性工厂方法的更改
DefaultTask
上的属性工厂方法现在是 final 的
属性工厂方法(如 newInputFile()
)旨在从扩展 DefaultTask
的类型的构造函数中调用。这些方法现在是 final 的,以避免子类覆盖这些方法并使用未初始化的状态。
输入和输出不再自动注册
这些方法返回的 Property 实例不再自动注册为任务的输入或输出。Property 实例需要在通常的方式中声明为输入或输出,例如附加 @OutputFile
等注解或使用运行时 API 注册属性。
例如,您以前可以使用以下语法,并将两个 outputFile 实例都注册为声明的输出
class MyTask extends DefaultTask {
// note: no annotation here
final RegularFileProperty outputFile = newOutputFile()
}
task myOtherTask {
def outputFile = newOutputFile()
doLast { ... }
}
open class MyTask : DefaultTask() {
// note: no annotation here
val outputFile: RegularFileProperty = newOutputFile()
}
task("myOtherTask") {
val outputFile = newOutputFile()
doLast { ... }
}
现在您必须显式注册 outputFile
,像这样
class MyTask extends DefaultTask {
@OutputFile // property needs an annotation
final RegularFileProperty outputFile = project.objects.fileProperty()
}
task myOtherTask {
def outputFile = project.objects.fileProperty()
outputs.file(outputFile) // or to be registered using the runtime API
doLast { ... }
}
open class MyTask : DefaultTask() {
@OutputFile // property needs an annotation
val outputFile: RegularFileProperty = project.objects.fileProperty()
}
task("myOtherTask") {
val outputFile = project.objects.fileProperty()
outputs.file(outputFile) // or to be registered using the runtime API
doLast { ... }
}
[5.0] Gradle 现在为 Java 9 及更高版本捆绑 JAXB
为了使用 S3 支持的工件仓库,您以前必须在 Java 9 及更高版本上运行时将 --add-modules java.xml.bind
添加到 org.gradle.jvmargs
。
由于 Java 11 不再包含 java.xml.bind
模块,Gradle 现在捆绑了 JAXB 2.3.1 (com.sun.xml.bind:jaxb-impl
) 并在 Java 9 及更高版本上使用它。
请从 org.gradle.jvmargs
中删除 --add-modules java.xml.bind
选项(如果已设置)。
[5.0] gradlePluginPortal()
仓库默认不再查找没有 POM 的 JAR
使用这种新行为,如果 gradlePluginPortal()
仓库中找到的插件或插件的传递依赖项没有 Maven POM,则解析将失败。
发布到没有 POM 的 Maven 仓库的工件应该修复。如果您遇到此类工件,请要求插件或库作者发布带有正确元数据的新版本。
如果您被不良插件困扰,您可以通过重新启用 JAR 作为 gradlePluginPortal()
仓库的元数据源来解决
pluginManagement {
repositories {
gradlePluginPortal().tap {
metadataSources {
mavenPom()
artifact()
}
}
}
}
pluginManagement {
repositories {
gradlePluginPortal().apply {
(this as MavenArtifactRepository).metadataSources {
mavenPom()
artifact()
}
}
}
}
Java Library Distribution Plugin 利用 Java Library Plugin
此外,插件创建的默认分发将包含 runtimeClasspath
配置的所有工件,而不是已弃用的 runtime
配置。
配置避免 API 禁止常见的配置错误
配置避免 API 在 Gradle 4.9 中引入,允许您避免创建和配置从未使用过的任务。
使用现有的 API,此示例添加了两个任务(foo
和 bar
)
tasks.create("foo") {
tasks.create("bar")
}
tasks.create("foo") {
tasks.create("bar")
}
当将其转换为使用新的 API 时,会发生一些令人惊讶的事情:bar
不存在。新的 API 仅在必要时执行配置操作,因此任务 bar
的 register()
仅在配置 foo
时执行。
tasks.register("foo") {
tasks.register("bar") // WRONG
}
tasks.register("foo") {
tasks.register("bar") // WRONG
}
为避免这种情况,Gradle 现在检测到这一点,并在使用新 API 时阻止修改底层容器(通过 create()
或 register()
)。
[5.0] Worker API:worker 的工作目录不再可以设置
由于 JDK 11 不再支持更改正在运行的进程的工作目录,因此现在禁止通过其 fork 选项设置 worker 的工作目录。
所有 worker 现在都使用相同的工作目录以启用重用。
请将文件和目录作为参数传递。
[4.10] 发布到 AWS S3 需要新的权限
S3 仓库传输协议允许 Gradle 将工件发布到 AWS S3 存储桶。从此版本开始,上传到 S3 存储桶的每个工件都将配备 bucket-owner-full-control
预置 ACL。确保用于发布工件的 AWS 帐户具有 s3:PutObjectAcl
和 s3:PutObjectVersionAcl
权限,否则上传将失败。
{
"Version":"2012-10-17",
"Statement":[
// ...
{
"Effect":"Allow",
"Action":[
"s3:PutObject", // necessary for uploading objects
"s3:PutObjectAcl", // required starting with this release
"s3:PutObjectVersionAcl" // if S3 bucket versioning is enabled
],
"Resource":"arn:aws:s3:::myCompanyBucket/*"
}
]
}
有关更多信息,请参阅 AWS S3 跨账户访问。
[4.9] 考虑尝试用于任务创建和配置的惰性 API
Gradle 4.9 引入了一种新的延迟创建和配置任务的方式。当您对配置成本高昂的任务或当您有许多任务时使用此方法,如果这些任务不运行,您的构建配置时间可以显着减少。
[4.8] 切换到 Maven Publish 和 Ivy Publish Plugins
既然发布插件是稳定的,我们建议您从标准 Java 项目(即基于 Java Plugin 的项目)的旧版发布机制迁移。这包括使用以下任何一个的项目:Java Library Plugin、Application Plugin 或 War Plugin。
要使用新方法,只需将任何 upload<Conf>
配置替换为 publishing {}
代码块。有关更多信息,请参阅 发布概述章节。
[4.8] 对发布插件使用延迟配置
在 Gradle 4.8 之前,publishing {}
代码块被隐式地视为好像其中的所有逻辑都在项目评估后执行。这令人困惑,因为它是唯一以这种方式运行的代码块。作为 Gradle 4.8 中稳定化工作的一部分,我们正在弃用此行为,并要求所有用户迁移他们的构建。
可以通过将以下内容添加到您的 settings 文件来开启新的稳定行为
enableFeaturePreview('STABLE_PUBLISHING')
enableFeaturePreview("STABLE_PUBLISHING")
我们建议使用本地仓库进行测试运行,以查看所有工件是否仍具有预期的坐标。在大多数情况下,一切都应该像以前一样工作,您就完成了。但是,您的发布代码块可能依赖于隐式延迟配置,特别是如果它依赖于在构建的配置阶段可能更改的值。
例如,在新行为下,以下逻辑假定 jar.archiveBaseName
在设置 artifactId
后不会更改
subprojects {
publishing {
publications {
mavenJava {
from components.java
artifactId = jar.archiveBaseName
}
}
}
}
subprojects {
publishing {
publications {
named<MavenPublication>("mavenJava") {
from(components["java"])
artifactId = tasks.jar.get().archiveBaseName.get()
}
}
}
}
如果该假设不正确或将来可能不正确,则必须在 afterEvaluate {}
代码块中设置 artifactId
,如下所示
subprojects {
publishing {
publications {
mavenJava {
from components.java
afterEvaluate {
artifactId = jar.archiveBaseName
}
}
}
}
}
subprojects {
publishing {
publications {
named<MavenPublication>("mavenJava") {
from(components["java"])
afterEvaluate {
artifactId = tasks.jar.get().archiveBbaseName.get()
}
}
}
}
}
[4.8] 配置现有的 wrapper
和 init
任务
您不应再定义自己的 wrapper
和 init
任务。而是配置现有任务,例如通过将此
task wrapper(type: Wrapper) {
...
}
task<Wrapper>("wrapper") {
...
}
转换为此
wrapper {
...
}
tasks.wrapper {
...
}
[4.8] Gradle 现在遵循 Maven POM 排除中的隐式通配符
如果 Maven POM 中的排除缺少 groupId
或 artifactId
,Gradle 过去会忽略该排除。现在,缺少的元素被视为隐式通配符——例如 <groupId>*</groupId>
——这意味着您的某些依赖项现在可能被排除在以前没有排除的地方。
您将需要显式声明您需要的任何缺少的依赖项。
[4.7] Gradle 的纯文本控制台输出的结构更改
纯文本控制台模式现在以与富文本控制台一致的方式格式化输出,这意味着输出格式已更改。例如
-
给定任务产生的输出现在组合在一起,即使其他任务与其并行执行。
-
任务执行标头以 "> Task" 前缀打印。
-
在构建执行期间产生的所有输出都写入标准输出文件句柄。这包括写入 System.err 的消息,除非您将标准错误重定向到文件或任何其他非控制台目标。
这可能会破坏从纯文本控制台输出中抓取详细信息的工具。
[4.6] 与编译、链接和安装相关的原生任务的 API 更改
许多与编译、链接和安装原生库和应用程序相关的任务已转换为 Provider API,以便它们支持 惰性配置。此转换对任务的 API 引入了一些破坏性更改,以便它们符合 Provider API 的约定。
以下任务已更改
- AbstractLinkTask 及其子类
-
-
getDestinationDir()
已替换为getDestinationDirectory()
。 -
getBinaryFile()
、getOutputFile()
已替换为getLinkedFile()
。 -
setOutputFile(File)
已移除。请使用Property.set()
代替。 -
setOutputFile(Provider)
已移除。请使用Property.set()
代替。 -
getTargetPlatform()
已更改为返回Property
。 -
setTargetPlatform(NativePlatform)
已移除。请使用Property.set()
代替。 -
getToolChain()
已更改为返回Property
。 -
setToolChain(NativeToolChain)
已移除。请使用Property.set()
代替。
-
- CreateStaticLibrary
-
-
getOutputFile()
已更改为返回Property
。 -
setOutputFile(File)
已移除。请使用Property.set()
代替。 -
setOutputFile(Provider)
已移除。请使用Property.set()
代替。 -
getTargetPlatform()
已更改为返回Property
。 -
setTargetPlatform(NativePlatform)
已移除。请使用Property.set()
代替。 -
getToolChain()
已更改为返回Property
。 -
setToolChain(NativeToolChain)
已移除。请使用Property.set()
代替。 -
getStaticLibArgs()
已更改为返回ListProperty
。 -
setStaticLibArgs(List)
已移除。请使用ListProperty.set()
代替。
-
- InstallExecutable
-
-
getSourceFile()
已替换为getExecutableFile()
。 -
getPlatform()
已替换为getTargetPlatform()
。 -
setTargetPlatform(NativePlatform)
已移除。请使用Property.set()
代替。 -
getToolChain()
已更改为返回Property
。 -
setToolChain(NativeToolChain)
已移除。请使用Property.set()
代替。
-
以下任务也看到了类似的更改
[4.6] Visual Studio 集成仅支持构建的所有组件的单个解决方案文件
VisualStudioExtension 不再具有 solutions
属性。相反,您可以在根项目中通过 VisualStudioRootExtension 配置单个解决方案,如下所示
model {
visualStudio {
solution {
solutionFile.location = "vs/${name}.sln"
}
}
}
此外,不再有为每个组件生成解决方案文件的单个任务,而是一个 visualStudio
任务,它生成一个包含构建中所有组件的解决方案文件。
[4.5] HttpBuildCache
不再遵循重定向
当通过 HttpBuildCache
连接到 HTTP 构建缓存后端时,Gradle 不再遵循重定向,而是将其视为错误。从构建缓存后端获取重定向主要是配置错误——例如,使用 "http" URL 而不是 "https"——并且对性能有负面影响。
[4.4] 第三方依赖项升级
此版本包括几个第三方依赖项的升级
-
jackson: 2.6.6 → 2.8.9
-
plexus-utils: 2.0.6 → 2.1
-
xercesImpl: 2.9.1 → 2.11.0
-
bsh: 2.0b4 → 2.0b6
-
bouncycastle: 1.57 → 1.58
这修复了以下安全问题
-
CVE-2017-7525(严重)
-
SONATYPE-2017-0359(严重)
-
SONATYPE-2017-0355(严重)
-
SONATYPE-2017-0398(严重)
-
CVE-2013-4002(严重)
-
CVE-2016-2510(严重)
-
SONATYPE-2016-0397(严重)
-
CVE-2009-2625(严重)
-
SONATYPE-2017-0348(严重)
Gradle 不会为这些第三方依赖项公开公共 API,但那些自定义 Gradle 的用户会希望知道这一点。