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、Jörgen Andersson、Marie、pandaninjas、Philip Wedemann、Ryan Schmitt、Steffen Yount、Tyler Kinkade、Zed Spencer-Milnes
务必查看公开路线图,了解对未来版本的规划。
通过更新包装器将构建切换为使用 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 https://docs.gradle.org.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
)现在可以用作Exec
和JavaExec
任务的standardInput
、standardOutput
和errorOutput
,而不会破坏配置缓存。
用户创建的任务具有类型为 java.io.InputStream
和 java.io.OutputStream
的属性,还可以使用标准流作为属性值。不支持使用 System.setIn
、System.setOut
和 System.setErr
设置自定义标准流。
嵌入式 Kotlin 已从 1.9.10 更新到 Kotlin 1.9.22。
现在,从 Java 代码生成的 Javadoc 支持“since”部分,指示引入该功能的 Gradle 版本。
这些信息来自 Javadoc 中的 @since
标记,但直到现在才显示。可以在 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 如何管理用于并行测试执行的线程。
现在可以在 TestNGOptions
上配置 threadPoolFactoryClass
参数,适用于支持它的 TestNG 版本(即 TestNG 7.0.0 及更高版本)。
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。
如果您发现此版本存在问题,请根据我们的问题准则在GitHub 问题中提交错误报告。如果您不确定自己是否遇到错误,请使用论坛。