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 Johannes约尔根·安德森玛丽熊猫忍者菲利普·韦德曼瑞安·施密特史蒂芬·扬特泰勒·金凯德泽德·斯宾塞-米尔尼斯

请务必查看公共路线图,以深入了解未来版本的计划。

目录

升级说明

通过更新包装器将您的构建切换为使用 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 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.inSystem.outSystem.err)现在可以用作standardInputstandardOutputerrorOutputofExecJavaExec任务,而不会破坏配置缓存。

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

Kotlin DSL 改进

嵌入式 Kotlin 升级至 1.9.22

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

Kotlin DSL 参考更新

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

该信息来自@sinceJavadoc 中的标签,目前尚未显示。可以在以下位置找到示例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如何管理线程以进行并行测试执行。

现在可以为支持它的 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 操作。

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

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

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

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

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

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

已解决的问题

已知的问题

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

外部贡献

我们喜欢从 Gradle 社区获得贡献。有关贡献的信息,请参阅gradle.org/contribute

报告问题

如果您发现此版本有问题,请按照我们的问题指南在GitHub 问题上提交错误。如果您不确定是否遇到错误,请使用论坛

我们希望您能通过 Gradle 获得快乐,并期待您通过TwitterGitHub获得反馈。