本章提供将 Gradle 8.14.3 构建迁移到 Gradle 9.0.0 所需的信息。有关 Gradle 8.x 内部迁移,请首先参阅旧版迁移指南

我们建议所有用户执行以下步骤

  1. 尝试运行 gradle help --scan 并查看生成的构建扫描的弃用视图

    Deprecations View in a Build Scan

    这能让你看到适用于你的构建的任何弃用警告。

    或者,您可以运行 gradle help --warning-mode=all 在控制台中查看弃用,尽管它可能不会报告那么多详细信息。

  2. 更新您的插件。

    某些插件可能会在新版 Gradle 中失效,因为这些版本可能会移除公共 API。使用最新版本的插件会增加其与新版 Gradle 兼容的可能性。

  3. 运行 gradle wrapper --gradle-version 9.0.0 将项目更新到 9.0.0。

  4. 尝试运行项目并使用故障排除指南调试任何错误。

运行时要求和 DSL 变更

要求 Java 虚拟机 (JVM) 17 或更高版本

Gradle 9.0.0 需要 Java 虚拟机 (JVM) 17 或更高版本才能运行 Gradle Daemon。这是与之前版本的破坏性变更,之前版本支持 JVM 8 及更高版本。

你的构建仍然可以使用工具链针对较低的 JVM 版本进行编译、测试和其他工作(Checkstyle、Javadoc 等)。

Gradle wrapper 和命令行启动器可以使用 JVM 8 运行,但它仍然需要较新的 JVM 才能启动构建。有关更多信息,请参阅下面的在旧版 JVM 上运行 Gradle 部分。

Gradle Tooling APITestKit 仍与 JVM 8 及更高版本兼容。

升级到 Kotlin 2.2.0

Gradle 现在嵌入了 Kotlin 2.2.0,从之前嵌入的版本 2.0.21 进行了升级。

有关完整详细信息和潜在的破坏性变更,请查阅 Kotlin 发行说明

Kotlin DSL 和插件使用 Kotlin 语言版本 2.2

Kotlin DSL 已升级到最新的稳定 Kotlin 2.2.x 运行时,并在整个工具链中使用 Kotlin 语言版本 2.2。这标志着与 Gradle 8.x 的转变,Gradle 8.x 从 8.11 开始嵌入了 Kotlin 2.0,但为了兼容性继续使用 Kotlin 语言版本 1.8。

此更改不仅影响 Kotlin DSL 脚本 (.gradle.kts),还影响用 Kotlin 编写的构建逻辑和插件(经典插件和约定插件)。用户应检查其代码与 Kotlin 2.2 的兼容性,因为 Kotlin 2.0Kotlin 2.1 都引入了多项破坏性语言更改。

由于 Kotlin 2 编译器处理脚本编译方式的更改,你不再能使用 this@Build_gradlethis@Settings_gradlethis@Init_gradle 等标签引用脚本实例。如果它们用于引用 DSL 脚本目标对象,则请改用 projectsettingsgradle。如果它们用于引用恰好与嵌套符号同名的顶级符号,则请使用不同的名称,可能通过添加中间变量来实现。

此次升级还包括对构建逻辑和插件作者的重要更改:已取消对 Kotlin 语言版本 1.4 到 1.7 的支持。

阅读下面的JSpecify 部分,了解 Kotlin 构建逻辑代码中与可空性相关的潜在破坏性变更。

升级到 Groovy 4.0.27

Groovy 已从版本 3.0.24 升级到 4.0.27。Groovy 4 的更新带来了许多破坏性变更,例如移除旧包、模块结构变更、解析器重写和字节码输出变更。有关 Groovy 3.x 到 4.x 语言变更的完整概述,请参阅 Groovy 4.0 发行说明。这些变更可能会影响直接或间接在 Gradle 中使用 Groovy 的用户,在极少数情况下,也会影响依赖传递依赖项的用户。

以前位于 groovy.util 等包中的常用 Groovy 类现在位于不同的包中,以适应 JPMS“拆分包要求”。请参阅此特定条目

Groovy 不再识别以 is 开头的 Boolean 属性

Groovy 4 不再将以 is 开头且返回类型为 Boolean 的 getter 视为属性。Gradle 目前仍将这些识别为属性,但此行为将在 Gradle 10 中更改以与 Groovy 4 对齐。有关更多详细信息,请参阅弃用通知

DELEGATE_FIRST 闭包在某些情况下可能现在更倾向于委托

Groovy 4 更改了使用 DELEGATE_FIRST 策略的闭包的行为。属性和方法的动态查找现在将优先于所有者,而不是委托。这可能导致在 Gradle 脚本中使用闭包时出现不同的行为,例如某些方法未找到或(例如,使用 .with { })某些动态属性优先于外部属性或方法。通常,这不应影响 Gradle 脚本,因为 Gradle 在其 API 中不使用具有动态属性的 DELEGATE_FIRST 闭包。

解决方法包括使用 @CompileStatic 避免动态查找,或根据需要显式使用 owner.this.super. 限定调用。

为了完全清晰,在 Groovy 3 中,查找顺序是

  1. 委托的 invokeMethod,它选择已知方法且不进行动态查找。

  2. 所有者的 invokeMethod,它选择已知方法且不进行动态查找。

  3. 委托的 invokeMissingMethod,它进行动态查找,包括通过属性。

  4. 所有者的 invokeMissingMethod,它进行动态查找,包括通过属性。

在 Groovy 4 中,查找顺序是

  1. 委托的 invokeMethod,它选择已知方法且不进行动态查找。

  2. 委托的 invokeMissingMethod,它进行动态查找,包括通过属性。

  3. 所有者的 invokeMethod,它选择已知方法且不进行动态查找。

  4. 所有者的 invokeMissingMethod,它进行动态查找,包括通过属性。

私有属性和方法在闭包中可能无法访问

在父类中定义并引用其私有属性或方法的闭包可能不再在子类中访问它们。这是由于 Groovy 错误,直到 Groovy 5 才会解决。这适用于用 Groovy 编写的构建脚本和插件。

作为解决方法,对类应用 @CompileStatic 以移除动态查找。

Groovy 3.x 代码可能无法访问超类方法

Groovy 4 改变了在运行时解析 super 方法调用的方式。因此,使用 Groovy 3.x 编译的代码可能无法访问 super 方法,因为代码不包含适当的运行时代码来定位它们。这仅适用于使用 Gradle 8.x 及更早版本的 Groovy 3.x 编写的插件。

插件变更

使用 Kotlin DSL 编写的插件需要 Gradle >= 8.11

在使用 Gradle 9.x.x 构建和发布使用 Kotlin DSL 的插件时,这些插件只能在 Gradle 8.11 或更高版本上使用。这是因为 Gradle 8.11 是第一个嵌入 Kotlin 2.0 或更高版本的版本,这是解释 Kotlin 元数据版本 2 所必需的。

如果你希望你的插件与旧版 Gradle 保持兼容,则必须明确将其编译为更早的 Kotlin 版本 (1.x)。

例如,为了支持 Gradle 6.8 及更高版本,将你的插件配置为面向 Kotlin 1.7,如下所示

build.gradle.kts
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    `kotlin-dsl`
}

tasks.withType<KotlinCompile>().configureEach {
    compilerOptions {
        languageVersion = KotlinVersion.KOTLIN_1_7
        apiVersion = KotlinVersion.KOTLIN_1_7
    }
}

有关每个 Gradle 版本中嵌入的 Kotlin 版本的详细信息,请参阅 Gradle 的兼容性矩阵

使用 Kotlin DSL 编写并使用 Gradle 7.x 或 8.x 发布的插件仍与 Gradle 6.8 及更高版本兼容。

使用 Groovy DSL 编写的插件需要 Gradle >= 7.0

使用 Groovy DSL 编写并使用 Gradle 9.x.x 构建的插件需要 Gradle 7.0 或更高版本才能运行。这是因为 Gradle 7.0 引入了 Groovy 3.0 支持,而 Gradle 9 嵌入了 Groovy 4.0。

由于 Gradle 9.0.0 内部使用 Groovy 4.0,因此使用它构建的插件在旧版 Gradle 上运行时可能不会按预期运行。为了获得最佳兼容性,此类插件应与 Gradle 9.0.0 或更高版本一起使用。

使用 Groovy DSL 编写并使用 Gradle 7.x 或 8.x 发布的插件仍与 Gradle 5.0 及更高版本兼容。

支持的最低 Kotlin Gradle 插件版本变更

从 Gradle 9.0.0 开始,支持的最低 Kotlin Gradle 插件版本为 2.0.0。更早的版本不再受支持,因为它们依赖于已移除的 Gradle API。

对于 Gradle 8.x,支持的最低版本是 1.6.10。

支持的最低 Android Gradle 插件版本变更

从 Gradle 9.0.0 开始,支持的最低 Android Gradle 插件版本为 8.4.0。更早的版本不再受支持,因为它们依赖于已移除的 Gradle API。

对于 Gradle 8.x,支持的最低版本是 7.3.0。

支持的最低 Gradle Enterprise 插件版本变更

从 Gradle 9.0.0 开始,支持的最低 Gradle Enterprise 插件版本为 3.13.1。更早的版本不再受支持,因为它们依赖于已移除的 Gradle API。

考虑升级到最新版本的 Gradle Enterprise 插件,或者更好的是,升级到最新版本的 Develocity 插件

对于 Gradle 8.x,支持的最低版本是 3.0。

C++ 和 Swift 插件不再依赖于基于软件模型的插件

Cpp 应用程序插件Cpp 库插件Swift 应用程序插件Swift 库插件已更新,不再依赖于软件模型插件基础架构。

因此,现在应直接在构建脚本的顶级配置 toolChains,而不是在 model { } 块中。

Scala 插件不再创建不可解析的配置

以前,Scala 插件使用名为 incrementalScalaAnalysisFor 的配置来解析项目之间的增量分析信息。但是,这些配置是不可解析的,可能导致 dependencies 报告中出现错误。

从 Gradle 9.0.0 开始,Scala 插件不再创建或使用这些配置。

设置文件变更

项目目录必须存在且可写

如果包含的项目与文件系统上不存在的目录不对应,或者目录存在但只读,Gradle 将失败。

例如,你可能会看到如下错误

* What went wrong:
Configuring project ':subproject1' without an existing directory is not allowed. The configured projectDirectory '.../subproject1' does not exist, can't be written to or is not a directory.

* Try:
> Make sure the project directory exists and is writable.

有关更多详细信息,请参阅 upgrading_version_8.html

任务变更

ValidatePlugins 任务现在需要 Java Toolchains

在 Gradle 9.0.0 中,在使用 ValidatePlugins 任务而不应用 Java Toolchains 插件将导致错误。

要解决此问题,请显式应用 jvm-toolchains 插件

build.gradle.kts
plugins {
    id("jvm-toolchains")
}
build.gradle
plugins {
    id 'jvm-toolchains'
}
jvm-toolchains 插件由 Java Library 插件和其他 JVM 相关插件自动应用。如果你已经应用了其中之一,则无需进一步操作。

归档任务 (Jar, Ear, War, Zip, AbstractArchiveTask) 默认生成可重现的归档

此更改可能会影响依赖于归档任务先前行为的现有构建,其中文件顺序不确定,并且文件时间戳和权限取自文件系统。

在 Gradle 9.0 中,归档任务(例如 JarEarWarZipAbstractArchiveTask)的默认行为已更改为默认生成可重现的归档。这意味着

  • 归档中的文件顺序现在是确定的。

  • 文件具有固定的时间戳(时间戳取决于归档类型)。

  • 所有目录的固定权限设置为 0755

  • 所有文件的固定权限设置为 0644

此更改提高了构建的可重现性,并确保生成的归档在不同环境中保持一致。

你可以通过以下配置恢复任务的一个或多个属性的先前行为

build.gradle.kts
tasks.withType<AbstractArchiveTask>().configureEach {
    // Make file order based on the file system
    isReproducibleFileOrder = false
    // Use file timestamps from the file system
    isPreserveFileTimestamps = true
    // Use permissions from the file system
    useFileSystemPermissions()
}
build.gradle
tasks.withType(AbstractArchiveTask).configureEach {
    // Makes file order non deterministic
    reproducibleFileOrder = false
    // Use file timestamps from the file system
    preserveFileTimestamps = true
    // Use permissions from the file system
    useFileSystemPermissions()
}

你还可以通过配置属性来保留归档任务之间的文件系统权限

gradle.properties
org.gradle.archives.use-file-system-permissions=true

Test 任务可能不再执行预期的测试

在以前的版本中,可以创建不带任何额外配置的 Test 任务。按照约定,Gradle 使用 test 源集的类路径和测试类。

build.gradle.kts
plugins {
    id("java-library")
}

// configure test dependencies
// ...

tasks.register<Test>("otherTest")
build.gradle
plugins {
    id 'java-library'
}

// configure test dependencies
// ...

tasks.register("otherTest", Test)

在此示例中,otherTest 依赖于弃用的约定。此场景在 8.1 中开始发出弃用警告。Gradle 将使用 otherTest 和内置的 test 任务执行相同的测试,因为 Gradle 使用了 test 源集的类路径和测试类。

约定已被移除,但如果构建依赖于此行为,则不会失败。发出弃用警告的构建将静默停止执行测试。在上面的示例中,otherTest 将被跳过且不执行任何测试,因为它没有配置测试类。

要恢复到以前的行为,你必须显式配置 Test 任务

build.gradle.kts
val test by testing.suites.existing(JvmTestSuite::class)
tasks.register<Test>("otherTest") {
    testClassesDirs = files(test.map { it.sources.output.classesDirs })
    classpath = files(test.map { it.sources.runtimeClasspath })
}
build.gradle
tasks.register("otherTest", Test) {
    testClassesDirs = testing.suites.test.sources.output.classesDirs
    classpath = testing.suites.test.sources.runtimeClasspath
}

或通过测试套件添加额外的 Test 任务

build.gradle.kts
testing {
    suites {
        named<JvmTestSuite>("test") {
            targets {
                register("otherTest")
            }
        }
    }
}
build.gradle
testing {
    suites {
        test {
            targets {
                otherTest
            }
        }
    }
}

如果未发现任何测试,test 任务将失败

当存在测试源且未应用任何过滤器时,如果 test 任务运行但未发现任何测试,它现在将因错误而失败。这是为了帮助防止测试是为一种测试框架编写但测试任务被错误配置为使用另一种测试框架的错误配置。如果应用了过滤器,则结果取决于 failOnNoMatchingTests 属性。

可以通过将测试任务配置中的 failOnNoDiscoveredTests 属性设置为 false 来禁用此行为

build.gradle.kts
tasks.withType<AbstractTestTask>().configureEach {
    failOnNoDiscoveredTests = false
}
build.gradle
tasks.withType(AbstractTestTask).configureEach {
    failOnNoDiscoveredTests = false
}

构建目录之外的陈旧输出不再被删除

在 Gradle 的早期版本中,位于构建目录之外的类文件在被视为陈旧时会被删除。这是作为源集输出注册的类文件的特殊情况。

由于这种设置不常见,并且强制 Gradle 在每次构建中急切地实现所有与编译相关的任务,因此该行为已在 Gradle 9.0.0 中删除。

Gradle 将继续根据需要清理构建目录内的陈旧输出。

modelcomponent 任务不再自动添加

modelcomponent 任务报告为项目配置的遗留软件模型对象的结构。以前,这些任务会自动添加到项目的每次构建中。现在,这些任务仅在应用基于规则的插件(例如 Gradle 对构建本机软件的支持提供的插件)时才添加到项目中。

API 变更

Gradle API 现在使用 JSpecify 可空性注解

自 Gradle 5.0 以来,Gradle 已在其公共 API 中支持空安全,从而可以在编写 Kotlin 构建脚本或 Java 或 Kotlin 插件代码时及早检测到空值问题。

以前,Gradle 使用来自现已休眠的 JSR-305 的注解来指示可空性。虽然有用,但 JSR-305 有局限性,并且不再积极维护。

从 Gradle 9.0.0 开始,Gradle API 现在使用 JSpecify 注解。JSpecify 为 Java API 中的可空性提供了现代、标准化的注解和语义,改进了 IDE 和编译期间的支持。

由于 JSpecify 的语义与 JSR-305 略有不同,因此你可能会在 Kotlin 或 Java 插件代码中看到新的警告或错误。这些通常表示你需要澄清或调整空处理的位置,现代编译器和 IDE 应提供有用的消息来指导你。

Kotlin 2.1 与 Gradle API 中的 JSpecify 注解结合使用,引入了更严格的可空性处理。由于更精确的类型检查,某些以前有效的代码现在可能无法编译。

常见的破坏性变更

  • 具有泛型边界的类型的无界泛型现在将无法编译。

    例如,如果你在 Provider<T> 上有一个 Kotlin 扩展函数,其签名是 fun <T> Provider<T>.some(),你必须将 <T> 限定为 <T : Any>,因为 Provider<T> 上的 T 不可为空。

  • 泛型边界的可空性现在被严格处理。

    例如,你不能再使用 Property<String?>,因为 Property<T> 中的 T 不可为空。

    另一个例子是使用 Gradle API 中接受 Map<String, *> 参数的函数;以前你可以传递具有可空值的映射,现在不能再这样做了。

使用 javax.annotation (JSR-305) 注解的插件在 Gradle 9.0.0 中将像以前一样继续工作。

公共 API 类型上的方法已设置为 final

方法 AndSpec.andGenerateBuildDashboard.aggregate 已声明为 final 以支持使用 @SafeVarargs 注解。

这些类型不打算被子类化。但是,如果你的构建逻辑或插件尝试覆盖这些方法,现在将导致运行时失败。

注入 getter 现在是 abstract

所有 Gradle 提供的具有 @Inject 注解 getter 的类现在都将其 getter 声明为 abstract。这将要求所有扩展 Gradle 提供的类的类都是 abstract

ConfigurationVariant.getDescription 现在是 Property<String>

此方法在 Gradle 7.5 中添加,以前是 Optional<String>。此属性不可通过公共 API 配置。

通过将描述设置为 Property<String>,辅助变体具有用户可配置的描述,该描述出现在outgoingVariants 报告中。

引入了 ComponentIdentifier 的新子类型

Gradle 9.0.0 引入了 RootComponentIdentifier,这是 ComponentIdentifier 的新子类型。

返回 ComponentIdentifier 实例的 API 现在可能返回此新类型的标识符实例。例如,ComponentResultResolvedVariantResultArtifactView API 等都受到影响。

在未来的 Gradle 版本中,可能会引入 ComponentIdentifier 的其他子类型。构建逻辑应保持对 Gradle API 返回的未知 ComponentIdentifier 子类型的弹性。

打包和构件行为变更

构件签名现在匹配 OpenPGP 密钥版本

从 Gradle 9.0.0 开始,signing 插件生成与所用密钥版本匹配的 OpenPGP 签名。此更改确保符合 RFC 9580 并引入对 OpenPGP 版本 6 密钥的支持。以前,Gradle 总是生成 OpenPGP 版本 4 签名,无论密钥版本如何。

Ear 和 War 插件使用 assemble 构建所有构件

在 Gradle 9.0.0 之前,将多个打包插件(例如,earwarjava)应用于同一个项目会导致特殊行为,即在 assemble 期间只构建一种构件类型。例如

  • 应用 ear 插件将跳过构建 warjar 构件。

  • 应用 war 插件将跳过构建 jar

此特殊处理已在 Gradle 9.0.0 中移除。现在,如果应用了多个打包插件,则在运行 assemble 任务时将构建所有相应的构件。例如,一个应用 earwarjava 插件的项目现在将在 assemble 期间生成 .ear.war.jar 文件。

Ear 和 War 插件将所有构件贡献给 archives 配置

在 Gradle 的早期版本中,应用多个打包插件(earwarjava)会导致 archives 配置的选择性行为。例如

  • 应用 ear 插件将 jarwar 构件排除在 archives 之外。

  • 应用 war 插件将 jar 构件排除在 archives 之外。

此行为已在 Gradle 9.0.0 中移除。现在,当应用多个打包插件时,所有相关的构件(EAR、WAR 和 JAR)都包含在 archives 配置中。

Gradle 不再在 assemble 期间隐式构建某些构件

在 Gradle 的早期版本中,assemble 任务将隐式构建 visible 标志未设置为 false 的任何配置中的构件。此行为已在 Gradle 9.0.0 中移除。

如果你有自定义配置并希望将其构件作为 assemble 的一部分构建,现在你需要明确声明构件和 assemble 任务之间的依赖关系

build.gradle.kts
val specialJar = tasks.register<Jar>("specialJar") {
    from("foo")
}

val special = configurations.create("special") {
    // In previous versions, this would have been enough to build the specialJar
    // artifact when running assemble
    outgoing.artifact(specialJar)
}

// In Gradle 9.0.0, you need to add a dependency from the artifact to the assemble task
tasks.named("assemble") {
    dependsOn(special.artifacts)
}
build.gradle
def specialJar = tasks.register("specialJar". Jar) {
    from("foo")
}

def special = configurations.create("special") {
    // In previous versions, this would have been enough to build the specialJar
    // artifact when running assemble
    outgoing.artifact(specialJar)
}

// In Gradle 9.0.0, you need to add a dependency from the artifact to the assemble task
tasks.named("assemble") {
    dependsOn(special.artifacts)
}

Gradle 不再隐式将某些构件添加到 archives 配置

在 Gradle 的早期版本中,archives 配置会自动包含 visible 标志未设置为 false 的任何配置中的构件。此隐式行为已在 Gradle 9.0.0 中移除。

要将自定义构件包含在 archives 配置中,你现在必须显式添加它

build.gradle.kts
val specialJar = tasks.register<Jar>("specialJar") {
    from("foo")
}

configurations {
    create("special") {
        // In previous versions, this would have been enough to add the specialJar
        // artifact to the archives configuration
        outgoing.artifact(specialJar)
    }
    // In Gradle 9.0.0, you need to explicitly add the artifact to the archives
    // configuration
    named("archives") {
        outgoing.artifact(specialJar)
    }
}
build.gradle
def specialJar = tasks.register("specialJar". Jar) {
    from("foo")
}

configurations {
    create("special") {
        // In previous versions, this would have been enough to add the specialJar
        // artifact to the archives configuration
        outgoing.artifact(specialJar)
    }
    // In Gradle 9.0.0, you need to explicitly add the artifact to the archives
    // configuration
    named("archives") {
        outgoing.artifact(specialJar)
    }
}

Gradle 模块元数据在从同一组件创建急切创建的发布后无法再修改

此行为以前导致警告:Gradle Module Metadata is modified after an eagerly populated publication.

现在将导致错误,建议查看相关文档。

配置缓存变更

不支持的构建事件监听器现在是配置缓存问题

构建事件监听器注册方法 BuildEventsListenerRegistry.onTaskCompletion 接受任何 OperationCompletionListener 实现的任意提供者。但是,当启用配置缓存时,目前仅支持从 BuildServiceRegistry.registerIfAbsentBuildServiceRegistration.getService 返回的提供者。

以前,当使用配置缓存时,不支持的提供者会被静默丢弃且从不接收事件。从 Gradle 9.0.0 开始,注册此类提供者现在会导致配置缓存问题并使构建失败。

如果你的构建以前与配置缓存一起工作(例如,监听器是非必要的),你可以暂时恢复到旧行为,方法是设置

org.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=true

此属性将在 Gradle 10 中移除。

现在,在警告模式下,对于不兼容的任务,配置缓存条目始终被丢弃

配置缓存通过允许显式将任务标记为不兼容来支持逐步迁移。当不兼容任务被调度执行时,缓存条目不会被存储,并且任务不会并行运行以确保正确性。配置缓存还可以通过启用 org.gradle.configuration-cache.problems=warn警告模式下运行,这会隐藏问题并允许存储和加载缓存条目,并并行运行任务,但可能存在问题。警告模式作为迁移和故障排除辅助工具存在,不打算作为忽略不兼容性的持久方式。

从 Gradle 9.0.0 开始,工作图中存在不兼容任务会导致缓存条目被丢弃,无论警告模式如何,以确保正确性。如果你以前依赖于警告模式,请考虑将违规任务标记为不兼容。然而,在配置缓存成熟度和生态系统采用的现阶段,我们建议解决不兼容性,以确保此功能带来的性能优势。

更新的版本

升级了代码质量工具的默认版本

Checkstyle 的默认版本是 10.24.0

CodeNarc 的默认版本是 3.6.0

Pmd 的默认版本是 7.13.0

升级了测试框架的默认版本

使用测试套件时,几个测试框架的版本已更改。

JUnit Jupiter 的默认版本是 5.12.2

TestNG 的默认版本是 7.11.0

Spock 的默认版本是 2.3

升级了 Eclipse JGit 的版本

Eclipse JGit 已从 5.13.3 更新到 7.2.1

此更新重构了 Gradle 配置 JGit 进行 SSH 操作的方式,并引入了对使用 SSH 代理的支持,利用了 JGit SSH 代理集成中可用的新功能。

已移除的 API 和功能

移除了已弃用的 JvmVendorSpec.IBM_SEMERU

已移除已弃用的 JvmVendorSpec.IBM_SEMERU 常量。其用法应替换为 JvmVendorSpec.IBM

移除了 GroovySourceSetScalaSourceSet 接口

以下源集接口已在 Gradle 9.0.0 中移除

  • org.gradle.api.tasks.GroovySourceSet

  • org.gradle.api.tasks.ScalaSourceSet

要配置 Groovy 或 Scala 源,请改用插件特定的 Source Directory Sets

例如,在插件中配置 Groovy 源

GroovySourceDirectorySet groovySources = sourceSet.getExtensions().getByType(GroovySourceDirectorySet.class);
groovySources.setSrcDirs(Arrays.asList("sources/groovy"));

移除了自定义构建布局选项

在 Gradle 9.0.0 中,已移除从命令行指定关键构建文件的自定义位置的功能。Gradle 8.x 中已弃用的以下选项不再受支持

  • -c, --settings-file — 指定设置文件的自定义位置

  • -b, --build-file — 指定构建文件的自定义位置

此外,GradleBuild 任务上的 buildFile 属性已移除。这意味着无法再通过 GradleBuild 任务设置自定义构建文件路径。

移除了约定

“约定”概念(由 org.gradle.api.plugins.Convention 类型表示)自 Gradle 8.2 起已被弃用,现在在 Gradle 9.0.0 中已完全移除。

以前注册已弃用约定的核心 Gradle 插件已相应更新。

这意味着移除了约定 API。这些已被移除

  • org.gradle.api.Task.getConvention()

  • org.gradle.api.Project.getConvention()

  • org.gradle.api.plugins.Convention

  • org.gradle.api.internal.HasConvention

使用这些 API 的现有插件将因 Gradle 9.0.0+ 而失败,应更新为使用 Extensions API。

下表显示了已移除的约定以及如何迁移

插件 访问 类型 解决方案

war

project.war

WarPluginConvention

直接配置 war 任务。

base

project.distDirName, project.libsDirName, project.archivesBaseName

BasePluginConvention

替换为 BasePluginExtension 类型的 project.base 扩展。

project-report

project.projectReports

ProjectReportPluginConvention

直接配置报告任务 (TaskReportTask, PropertyReportTask, DependencyReportTask, HtmlDependencyReportTask)。

ear

project.ear

EarPluginConvention

直接配置 ear 任务。

移除了 org.gradle.cache.cleanup

org.gradle.cache.cleanup 属性以前允许用户禁用自动缓存清理,现已在 Gradle 9.0.0 中移除。

此属性不再有任何效果。要在 Gradle 9.0.0 及更高版本中控制缓存清理行为,请改用init 脚本

移除了 buildCache.local.removeUnusedEntriesAfterDays

在 Gradle 9.0.0 中,属性 buildCache.local.removeUnusedEntriesAfterDays 已移除。

此属性以前用于配置本地构建缓存的保留期。

要配置本地构建缓存中未使用条目的保留期,请改用Gradle 用户主目录缓存清理设置

移除了已弃用的 org.gradle.util 成员

org.gradle.util 包的以下成员已移除

  • CollectionUtils

  • ConfigureUtil, ClosureBackedAction

    这些类以前提供与 groovy.lang.Closure 相关的实用程序。插件应避免在其 API 中依赖 Groovy 特性,例如 Closure。相反,插件应创建使用 Action 的方法

    abstract class MyExtension {
        // ...
        public void options(Action<? extends MyOptions>  action) {
            action.execute(options)
        }
    }

    Gradle 会在运行时为每个带有 Action 作为单个参数的方法自动生成一个接受 Closure 的方法,只要对象是使用 ObjectFactory#newInstance 创建的。

    作为最后的手段,要应用由 Groovy 闭包表示的某些配置,插件可以使用 Project#configure

移除了 IdeaModule 中已弃用的 testSourceDirstestResourceDirs

已从 org.gradle.plugins.ide.idea.model.IdeaModule 中移除了已弃用的 testSourceDirstestResourceDirs 属性。此更改不影响 Tooling API 中使用的 org.gradle.tooling.model.idea.IdeaModule 类型。请改用 testSourcestestResources 属性。

移除了基于 Unix 模式的文件权限

Gradle 9.0.0 移除了使用原始 Unix 模式整数指定文件权限的旧版 API。

Gradle 8.3 引入了新的、更具表现力的文件权限配置 API,并在 Gradle 8.8 中提升为稳定版。请参阅

Gradle 8.8 中已弃用的以下旧方法现已移除

  • org.gradle.api.file.CopyProcessingSpec.getFileMode()

  • org.gradle.api.file.CopyProcessingSpec.setFileMode(Integer)

  • org.gradle.api.file.CopyProcessingSpec.getDirMode()

  • org.gradle.api.file.CopyProcessingSpec.setDirMode(Integer)

  • org.gradle.api.file.FileTreeElement.getMode()

  • org.gradle.api.file.FileCopyDetails.setMode(int)

从 Gradle 发行版中移除了选定的 Groovy 模块

Gradle 9.0.0 从其捆绑发行版中移除了某些 Groovy 模块。它们将不再在类路径上可用,也无法通过 localGroovy 获得

  • groovy-test

  • groovy-console

  • groovy-sql

移除了 kotlinDslPluginOptions.jvmTarget

在 Gradle 9.0.0 中,kotlinDslPluginOptions.jvmTarget 属性已移除。

此属性以前用于配置使用 kotlin-dsl 插件编译的代码的 JVM 目标版本。

要设置目标 JVM 版本,现在应配置 Java 工具链

Kotlin DSL 中移除了 gradle-enterprise 插件块扩展

在基于 Kotlin DSL 的 settings.gradle.kts 文件中,你以前可以使用 gradle-enterprise 插件块扩展来应用与 gradle --scan 捆绑的相同版本的 Gradle Enterprise 插件

plugins {
    `gradle-enterprise`
}

此简写在 Groovy DSL (settings.gradle) 中没有等效项,现已移除。

Gradle Enterprise 已更名为 Develocity,插件 ID 已从 com.gradle.enterprise 更改为 com.gradle.develocity。因此,你现在必须使用其完整 ID 和版本明确应用插件

plugins {
    id("com.gradle.develocity") version "4.0.2"
}

如果你仍在使用旧名称,则可以应用已弃用的插件 ID 以方便过渡

plugins {
    id("com.gradle.enterprise") version "3.19.2"
}

我们强烈鼓励用户采用最新发布的 Develocity 插件版本,即使将其与旧版 Gradle 一起使用。

Kotlin DSL 中移除了急切构件配置访问器

在 Gradle 5.0 中,配置访问器的类型从 Configuration 更改为 NamedDomainObjectProvider<Configuration> 以支持惰性配置。为了保持与针对旧版 Gradle 编译的插件的兼容性,Kotlin DSL 提供了急切访问器扩展,例如

configurations.compileClasspath.files // equivalent to configurations.compileClasspath.get().files
configurations.compileClasspath.singleFile // equivalent to configurations.compileClasspath.get().singleFile

这些急切访问器在 Gradle 8.0 中被弃用并从公共 API 中移除,但仍可用于针对旧版 Gradle 编译的插件。

在 Gradle 9.0.0 中,这些旧方法现已完全移除。

Kotlin DSL 中 plugins {} 块的版本目录中移除了 librariesbundles

在 Gradle 8.1 中,在 Kotlin DSL 脚本的 plugins {} 块中访问依赖版本目录中的 librariesbundles 被弃用。

在 Gradle 9.0.0 中,此支持已完全移除。尝试在 plugins {} 块中引用 librariesbundles 现在将导致构建失败。

Kotlin DSL 中移除了 "name"() 任务引用语法

在 Gradle 9.0.0 中,已移除在 Kotlin DSL 中使用 "name"() 语法引用任务或其他领域对象的功能。

请改用 named("name") 或其他支持的表示法来引用任务或领域对象,而不是使用 "name"()

移除了 WriteProperties 任务中的 outputFile

WriteProperties 任务中的 outputFile 属性已在 Gradle 9.0.0 中移除。

此属性在 Gradle 8.0 中被弃用,并被 destinationFile 属性取代。

移除了 Project#execProject#javaexec 以及脚本级别的对应项

以下用于启动外部进程的辅助方法已在 Gradle 8.11 中弃用,现已在 Gradle 9.0.0 中移除

  • org.gradle.api.Project#exec(Closure)

  • org.gradle.api.Project#exec(Action)

  • org.gradle.api.Project#javaexec(Closure)

  • org.gradle.api.Project#javaexec(Action)

  • org.gradle.api.Script#exec(Closure)

  • org.gradle.api.Script#exec(Action)

  • org.gradle.api.Script#javaexec(Closure)

  • org.gradle.api.Script#javaexec(Action)

  • org.gradle.kotlin.dsl.InitScriptApi#exec(Action)

  • org.gradle.kotlin.dsl.InitScriptApi#javaexec(Action)

  • org.gradle.kotlin.dsl.KotlinScript#exec(Action)

  • org.gradle.kotlin.dsl.KotlinScript#javaexec(Action)

  • org.gradle.kotlin.dsl.SettingsScriptApi#exec(Action)

  • org.gradle.kotlin.dsl.SettingsScriptApi#javaexec(Action)

移除了未使用的公共 API

以下类型已在 Gradle 9.0.0 中移除。这些类型未在 Gradle 的公共 API 中使用,因此没有用处。

  • org.gradle.api.artifacts.ArtifactIdentifier

  • org.gradle.api.publish.ivy.IvyDependency

  • org.gradle.api.publish.maven.MavenDependency