Gradle 发行说明

Gradle 团队很高兴地宣布推出 Gradle 8.7。

Java 22 现支持编译、测试和运行基于 JVM 的项目。

现在可以借助构建缓存避免 Groovy DSL 的脚本编译

此外,此版本还包括对构建创作错误和警告消息配置缓存Kotlin DSL的改进。

有关详细信息,请参阅以下完整发行说明。

我们要感谢以下社区成员对 Gradle 此版本做出的贡献:Aleksandr PostnovBjörn KautlerBrice DutheilDenis BuzmakovFederico La PennaGregor DschungHal DeadmanHélio Fernandes SebastiãoIvan GavrilovicJendrik JohannesJörgen AnderssonMariepandaninjasPhilip WedemannRyan SchmittSteffen YountTyler KinkadeZed Spencer-Milnes

务必查看公开路线图,了解对未来版本的规划。

目录

升级说明

通过更新包装器将构建切换为使用 Gradle 8.7

./gradlew wrapper --gradle-version=8.7

参阅Gradle 8.x 升级指南,了解升级到 Gradle 8.7 时的弃用、重大更改和其他注意事项。

有关 Java、Groovy、Kotlin 和 Android 兼容性,请参阅完整兼容性说明

新功能和可用性改进

支持使用 Java 22 构建项目

现在,Gradle 支持使用 Java 22来编译、测试和启动其他 Java 程序。使用工具链选择语言版本。

你无法使用 Java 22 运行 Gradle 8.7 本身,因为 Groovy 仍需要支持 JDK 22。但是,预计未来版本将提供此支持。

借助构建缓存支持避免 Groovy 构建脚本编译

Gradle 构建缓存是一种旨在通过重复使用以前构建的本地或远程输出以节省时间而设计的机制。

在此版本中,Groovy 构建脚本编译可以受益于远程构建缓存,在启用时,通过完全避免此步骤,可以减少开发人员的初始构建时间。

虽然自 Gradle 5.0 中引入 Kotlin DSL 以来,Kotlin 构建脚本编译一直可以使用此功能,但 Groovy DSL 缺少此功能奇偶校验。

构建创作改进

随着构建变得越来越复杂,确定何时何地配置特定值可能具有挑战性。Gradle 提供了一种使用延迟配置有效管理此复杂性的方法。

用于更新集合属性的更好 API

此版本改进了延迟集合属性的 API,这是 Gradle 延迟配置的关键元素。在此版本之前,经典集合方法的交互、约定的概念以及围绕空提供程序的规则在某些情况下导致了用户令人惊讶的行为。根据社区反馈,此版本的 Gradle 引入了具有更清晰契约的用于更新集合的替代 API

新 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. 

可抑制的“dependencies-without-versions”验证错误

生成 Gradle 模块元数据文件时,Gradle 会通过查找常见的配置错误来防止您的项目发布损坏的元数据。

其中一个错误是发布元数据时依赖项没有版本。此验证错误现在可以被抑制,因为在某些情况下此类元数据是有效的

tasks.withType(GenerateModuleMetadata).configureEach {
    suppressedValidationErrors.add('dependencies-without-versions')
}

配置缓存改进

配置缓存通过缓存配置阶段的结果并在后续构建中重用它来改善构建时间。此功能可以显著提高构建性能。

配置缓存报告中更清晰的堆栈跟踪

配置缓存报告中显示的禁止 API 调用堆栈跟踪可能很长,并且包含不总是有助于解决问题的内部 Gradle 帧。在此版本中,内部堆栈帧默认折叠,以突出触发错误的构建逻辑

Collapsed stack frames in the configuration cache report

如果需要,仍然可以展开并检查折叠的帧。

支持标准流作为任务属性值

标准流(System.inSystem.outSystem.err)现在可以用作ExecJavaExec任务的standardInputstandardOutputerrorOutput,而不会破坏配置缓存。

用户创建的任务具有类型为 java.io.InputStreamjava.io.OutputStream 的属性,还可以使用标准流作为属性值。不支持使用 System.setInSystem.setOutSystem.setErr 设置自定义标准流。

Kotlin DSL 改进

嵌入式 Kotlin 升级到 1.9.22

嵌入式 Kotlin 已从 1.9.10 更新到 Kotlin 1.9.22

Kotlin DSL 参考更新

现在,从 Java 代码生成的 Javadoc 支持“since”部分,指示引入该功能的 Gradle 版本。

这些信息来自 Javadoc 中的 @since 标记,但直到现在才显示。可以在 JavaToolchainSpec 中找到示例。

其他改进

使用 Gradle init 生成简洁的项目

使用新的 --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 的 threadPoolFactoryClass 参数

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 操作。

此版本修复了通过符号链接间接引用内容更改的检测问题,从而提高了构建的正确性。

支持 JVM 测试套件依赖项块中的约束

Gradle 7.6 中引入的强类型依赖项块不支持依赖项约束。

在此版本中,现在可以添加依赖项约束

testing {
    suites {
        getByName<JvmTestSuite>("test") {
            dependencies {
                implementation(constraint("foo:bar:1.0"))
            }
        }
    }
}

目前不支持为每个部分提供单独的字符串或使用命名参数。

已修复问题

已知问题

已知问题是发布后发现的问题,与本版本中所做的更改直接相关。

外部贡献

我们非常欢迎 Gradle 社区的贡献。有关贡献的信息,请参阅gradle.org/contribute

报告问题

如果您发现此版本存在问题,请根据我们的问题准则在GitHub 问题中提交错误报告。如果您不确定自己是否遇到错误,请使用论坛

我们希望您能使用 Gradle 构建快乐,我们期待通过TwitterGitHub收到您的反馈。