Java 工具链介绍

目录

引言

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

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

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

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

不再需要调整 releasesourceCompatibility,也不再需要描述应为构建安装哪个 JDK 的 Wiki 页面。优点是巨大的,让我们看看如何使用它!

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 核心开发施加限制。例如,Java 8 之外的功能和 API 对于 Gradle 工程师来说是不可用的,无法用于开发工具。

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

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

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

  • JavaCompile
  • Test
  • Javadoc
  • JavaExec

计划在下一个 Gradle 版本中为 Groovy 和 Scala 插件添加工具链支持。

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

讨论