Java 工具链简介

目录

介绍

构建 Java 项目和运行 Gradle 都需要安装 JDK。大多数 Gradle 用户为了方便,都使用运行 Gradle 的 Java 安装来构建和测试他们的应用程序。

虽然这在简单情况下是可以接受的,但这种方法存在许多问题。例如,如果构建需要所有机器上使用相同的 Java 版本,则每个开发人员都需要知道该要求并手动安装该版本。

已经可以配置 Gradle 以使用与运行 Gradle 不同的 Java 版本来构建项目。但是,这需要分别配置每个任务,如编译、测试和 javadoc。

Gradle 6.7 引入了“Java 工具链支持”。简而言之,它允许您使用已安装的任何 Java 版本运行 Gradle,而 Gradle 使用在单个位置声明的 Java 版本构建项目。Gradle 将自动配置构建,检测已安装的 JDK,并在尚未安装时下载所需的 JDK。

不再需要 releasesourceCompatibility 调整,不再需要 wiki 页面描述您应该安装哪个 JDK 才能使构建工作。优点是巨大的,让我们看看如何使用它!

Java 工具链支持简介 #

Java 工具链支持使构建作者能够声明他们的项目编译、测试和运行代码所需的 Java 版本。

项目级配置 #

让我们从您作为构建作者需要做的最少的事情开始

plugins {
    id("java-library") // or id("application")
}

java {
    toolchain {
            languageVersion.set(JavaLanguageVersion.of(11))
    }
}

就是这样!

在 Gradle 6.7 中,您通过以上操作获得什么?

您获得

  • 所有 Java 编译任务都将使用 Java 11 进行构建。这意味着 maintest 源代码集中的代码,以及您添加的任何自定义源代码集中的 Java 代码,都将使用配置的 Java 版本构建。
  • 所有测试任务,包括默认的 test 任务和任何其他自定义 Test 任务,都将使用 Java 11 运行测试。
  • javadoc 任务将使用 Java 11 构建文档。

此外,使用 application 插件,run 任务将使用 Java 11 启动您的应用程序。

在幕后,Gradle 将会

如果 Gradle 找不到请求的 Java 版本,您可以告诉它 在哪里查找

任务级配置 #

在某些情况下,您需要为特定任务使用不同的工具链。假设您开发的库具有取决于其运行的 Java 版本的特定代码路径。您将希望确保两个代码路径都得到执行,因此将使用不同的 Java 版本运行一组测试。以下方式支持这种情况。

tasks.register<Test>("extraTests") {
    javaLauncher.set(javaToolchains.launcherFor {
        languageVersion.set(JavaLanguageVersion.of(14))
    })
}

前往 文档 了解更多信息。

工具链使用的更多益处 #

除了我们之前讨论的益处之外,工具链还可以在更多情况下提供帮助。

Gradle 在尚未发布的 Java 版本(如编写本文时的 Java 16)上构建代码是有问题的,这可能会导致运行现有版本的 Gradle(如当前的 6.7 版本)失败。

借助工具链支持,Gradle 6.7 完全能够使用尚未发布的语言版本编译和测试代码。您只需要要求它这样做

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(16))
    }
}

此外,使用不同的 Java 版本构建和运行代码可能会导致行为不同,从而可能导致难以诊断的问题。

即使没有影响系统行为的不兼容性,在不同的机器上使用不同的 Java 版本构建项目也可能会降低构建性能,因为 构建缓存 未命中。

放宽 Gradle 对 Java 版本的约束 #

除了对构建作者的好处之外,此功能还将对 Gradle 本身的开发产生影响。到目前为止,Gradle 假设它将使用与您的项目所需的 Java 版本相同的版本运行。这意味着 Gradle 必须能够使用一系列 Java 版本运行,以满足使用 Gradle 的项目的需求。在 Java 5 到 8 的发布节奏下,这可能是可以接受的。在新的 Java 发布计划中,这变得更加成问题。

从 6.7 版本开始,Gradle 要求

  • 最低 Java 8 才能运行构建,
  • 每天使用 11 构建
  • 并测试到 Java 15。

所有这些都需要相当复杂的 CI 设置,并对 Gradle 核心开发施加约束。例如,Gradle 工程师无法访问 Java 8 之外的功能和 API 来开发该工具。

一旦社区采用工具链,我们最终将能够放宽对 Gradle 运行时要求的限制。然后,Gradle 可能仅在相对较新的 Java 版本上运行,同时支持通过工具链为较旧的 Java 版本构建代码。

工具链的下一步是什么? #

在 Gradle 6.7 中,工具链支持仅限于 Java 专用插件已知的任务

  • JavaCompile
  • Test
  • Javadoc
  • JavaExec

Groovy 和 Scala 插件的工具链支持计划在接下来的 Gradle 版本之一中添加。

我们还希望,鉴于此功能对用户的益处,社区 插件作者将在他们自己的任务中利用工具链支持

讨论