Gradle 团队很高兴宣布推出 Gradle 8.7。
Java 22现在支持编译、测试和运行基于 JVM 的项目。
由于构建缓存,现在可以避免 Groovy DSL 的脚本编译。
此外,此版本还包括对构建创作、错误和警告消息、配置缓存以及Kotlin DSL 的改进。
有关详细信息,请参阅下面的完整发行说明。
我们要感谢以下社区成员为本次 Gradle 版本做出的贡献:Aleksandr Postnov、Björn Kautler、Brice Dutheil、Denis Buzmakov、Federico La Penna、Gregor Dschung、Hal Deadman、Hélio Fernandes Sebastião、Ivan Gavrilovic、Jendrik Johannes、约尔根·安德森、玛丽、熊猫忍者、菲利普·韦德曼、瑞安·施密特、史蒂芬·扬特、泰勒·金凯德、泽德·斯宾塞-米尔尼斯
请务必查看公共路线图,以深入了解未来版本的计划。
通过更新包装器将您的构建切换为使用 Gradle 8.7:
./gradlew wrapper --gradle-version=8.7
请参阅Gradle 8.x 升级指南,了解升级到 Gradle 8.7 时的弃用、重大更改和其他注意事项。
有关 Java、Groovy、Kotlin 和 Android 兼容性的信息,请参阅完整的兼容性说明。
Gradle 现在支持使用 Java 22来编译、测试和启动其他 Java 程序。选择语言版本是使用工具链完成的。
您无法使用 Java 22 运行 Gradle 8.7 本身,因为 Groovy 仍然需要支持 JDK 22。但是,未来的版本预计将提供此支持。
Gradle构建缓存是一种旨在通过重用先前构建的本地或远程输出来节省时间的机制。
在此版本中,Groovy 构建脚本编译可以受益于远程构建缓存,启用该缓存后,可以完全避免此步骤,从而减少开发人员的初始构建时间。
虽然自 Gradle 5.0 中引入 Kotlin DSL 以来,此功能已可用于 Kotlin 构建脚本编译,但 Groovy DSL 缺乏此功能。
随着构建的复杂性不断增加,确定配置特定值的时间和地点可能会很困难。 Gradle 提供了一种使用惰性配置来管理这种复杂性的有效方法。
此版本改进了惰性集合属性的 API,这是 Gradle 惰性配置的关键元素。在此版本之前,经典收集方法的交互、约定的概念以及空提供者的规则在某些场景中导致了用户的令人惊讶的行为。根据社区反馈,此版本的 Gradle 引入了替代 API,用于通过更清晰的契约更新集合:
HasMultipleValues.append*(...)
它们是更方便的替代品HasMultipleValues.add*(...)
。MapProperty.insert*(...)
它们是更方便的替代品MapProperty.put*(...)
。新的 API 具有以下优势:
一个常见的抱怨是添加值(使用ListProperty.add(...)
,SetProperty.add(...)
或MapProperty.put(...)
在约定值之上会导致丢失约定值。
例如,在应用的插件中,列表属性ListProperty<String>
是按照约定配置的:
listProp.convention(listOf("one"))
在构建文件中,构建作者将元素添加到该列表属性中:
listProp.add("two")
// listProp now only contains "two", that’s confusing
然而,正如片段中所解释的,这种行为令人惊讶。新引入的方法(例如ListProperty.append(...)
、SetProperty.append(...)
和MapProperty.insert(...)
)允许用户表达应保留约定:
listProp.append("two")
// listProp now contains ["one", "two"], as expected
另一个常见的混乱来源是如何在集合属性中处理空提供程序。例如,使用向集合属性添加空提供程序add(...)
将导致整个属性也变得没有任何值。
listProp.add("one")
listProp.add(providers.environmentVariable("myEnvVar"))
// listProp will be empty if `myEnvVar` is not defined
为了避免这种行为,您可以使用此版本中引入的新更新 API(例如ListProperty.append(...)
、SetProperty.append(...)
和MapProperty.insert(...)
):
listProp.append("one")
listProp.append(providers.environmentVariable("myEnvVar"))
// listProp will still contain "one" if myEnvVar is not defined
Gradle 提供了一组丰富的错误和警告消息来帮助您理解和解决构建中的问题。
当应用需要更高版本 Gradle 的插件时(通过指定org.gradle.plugin.api-version
属性),依赖解析失败时的错误消息现在将清楚地说明问题:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'example'.
> Could not resolve all files for configuration ':classpath'.
> Could not resolve com.example:plugin:1.0.
Required by:
project : > com.example.greeting:com.example.greeting.gradle.plugin:1.0
> Plugin com.example:plugin:1.0 requires at least Gradle 8.0. This build uses Gradle 7.6.
* Try:
> Upgrade to at least Gradle 8.0. See the instructions at http://gradle.github.net.cn/8.7/userguide/upgrading_version_8.html#sub:updating-gradle.
> Downgrade plugin com.example:plugin:1.0 to an older version compatible with Gradle 7.6.
失败的建议解决方案将包括升级 Gradle 版本或降级插件版本。这取代了之前的低级不兼容消息,其中包含有关插件请求中涉及的所有属性的详细信息。
当在任务中包含压缩存档Copy
会导致重复文件并被DuplicatesStrategy.Fail
使用时,错误消息现在将清楚地说明问题:
Cannot copy file <SOURCE_FILE> to <DESTINATION_DIR> because file <OTHER_SOURCE_FILE> has already been copied there.
生成 Gradle 模块元数据文件时,Gradle 通过查找常见配置错误来防止您的项目发布损坏的元数据。
这些错误之一是发布具有没有版本的依赖项的元数据。现在可以抑制此验证错误,因为在某些用例中此类元数据有效:
tasks.withType(GenerateModuleMetadata).configureEach {
suppressedValidationErrors.add('dependencies-without-versions')
}
配置缓存通过缓存配置阶段的结果并将其重用于后续构建来缩短构建时间。此功能可以显着提高构建性能。
配置缓存报告中显示的禁止 API 调用的堆栈跟踪可能很长,并且包含内部 Gradle 帧,这些帧并不总是有助于解决问题。在此版本中,默认情况下会折叠内部堆栈帧以突出显示触发错误的构建逻辑:
如有必要,折叠的框架仍然可以展开和检查。
标准流(System.in
、System.out
和System.err
)现在可以用作standardInput
、standardOutput
和errorOutput
ofExec
和JavaExec
任务,而不会破坏配置缓存。
用户创建具有类型属性的任务java.io.InputStream
,也java.io.OutputStream
可以使用标准流作为属性值。不支持使用System.setIn
、System.setOut
、 和设置自定义标准流。System.setErr
嵌入式 Kotlin 已从 1.9.10 更新到Kotlin 1.9.22。
从 Java 代码生成的 Javadoc 现在支持“since”部分,指示引入该功能时的 Gradle 版本。
该信息来自@since
Javadoc 中的标签,目前尚未显示。可以在以下位置找到示例JavaToolchainSpec
。
使用新--no-comments
选项允许Gradle init生成包含没有注释的代码的新项目。生成的构建文件和源文件更小且更简洁。
gradle init --use-defaults --type kotlin-library --no-comments
您可以通过在Gradle 属性org.gradle.buildinit.comments
中配置该属性来永久设置此首选项。false
Gradle 使任务能够通过构建服务共享状态或资源,例如预先计算的值或外部服务,构建服务是保存任务使用状态的对象。构建服务可以选择接受参数,Gradle 在创建服务实例时将其注入到服务实例中。
现在可以注册不需要额外配置的共享构建服务,registerIfAbsent()
而无需使用更新的方法提供空配置操作:
gradle.sharedServices.registerIfAbsent("counter", CountingService, voidAction) // Old method
gradle.sharedServices.registerIfAbsent("counter", CountingService) // New method
TestNG是 Gradle 支持的测试框架。在TestNG中,该threadPoolFactoryClass
属性用于指定自定义线程池工厂类,该类详细说明了TestNG如何管理线程以进行并行测试执行。
现在可以为支持它的 TestNG 版本(即 TestNG 7.0.0 及更高版本)threadPoolFactoryClass
配置该参数:TestNGOptions
testing {
suites {
test {
useTestNG("7.5")
targets {
all {
testTask.configure {
options.threadPoolFactoryClass = "com.example.MyThreadPoolFactory"
}
}
}
}
}
}
如果为不支持该参数的 TestNG 版本设置此参数,则会出现错误。
为了降低安全风险并避免在项目中集成受损的依赖项,Gradle 支持依赖项验证。依赖性验证通常使用校验和或数字签名来完成。 Gradle 验证下载的工件是否与预期的校验和匹配或使用受信任的密钥进行签名。
在此版本之前, Gradle 未对元数据验证文件中的忽略键列表进行正确排序,因此顺序会根据执行顺序而变化,从而影响文件的构建和校验和的可重复性。在此版本中,无论执行顺序如何,都保证保留顺序。
Gradle 维护一个虚拟文件系统(VFS) 来计算在项目的重复构建中需要重建的内容。通过监视文件系统,Gradle 在构建之间保持 VFS 最新,从而减少所需的 I/O 操作。
此版本修复了检测通过符号链接间接引用的内容更改的问题,提高了构建的正确性。
Gradle 7.6 中引入的强类型依赖块不支持依赖约束。
在此版本中,现在可以添加依赖约束:
testing {
suites {
getByName<JvmTestSuite>("test") {
dependencies {
implementation(constraint("foo:bar:1.0"))
}
}
}
}
目前不支持为每个部分提供单独的字符串或使用命名参数。
已知问题是发布后发现的与此版本中所做的更改直接相关的问题。
我们喜欢从 Gradle 社区获得贡献。有关贡献的信息,请参阅gradle.org/contribute。