Java 工具链简介
介绍
构建 Java 项目和运行 Gradle 都需要安装 JDK。大多数 Gradle 用户为了方便,都使用运行 Gradle 的 Java 安装来构建和测试他们的应用程序。
虽然这在简单情况下是可以接受的,但这种方法存在许多问题。例如,如果构建需要所有机器上使用相同的 Java 版本,则每个开发人员都需要知道该要求并手动安装该版本。
已经可以配置 Gradle 以使用与运行 Gradle 不同的 Java 版本来构建项目。但是,这需要分别配置每个任务,如编译、测试和 javadoc。
Gradle 6.7 引入了“Java 工具链支持”。简而言之,它允许您使用已安装的任何 Java 版本运行 Gradle,而 Gradle 使用在单个位置声明的 Java 版本构建项目。Gradle 将自动配置构建,检测已安装的 JDK,并在尚未安装时下载所需的 JDK。
不再需要 release
或 sourceCompatibility
调整,不再需要 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 进行构建。这意味着
main
和test
源代码集中的代码,以及您添加的任何自定义源代码集中的 Java 代码,都将使用配置的 Java 版本构建。 - 所有测试任务,包括默认的
test
任务和任何其他自定义Test
任务,都将使用 Java 11 运行测试。 javadoc
任务将使用 Java 11 构建文档。
此外,使用 application
插件,run
任务将使用 Java 11 启动您的应用程序。
在幕后,Gradle 将会
- 从 已知位置(如 asdf、jabba、SDKMAN! 或每个操作系统的标准位置)列表中找到 Java 11 安装
- 验证安装及其版本
- 如果未找到 Java 11 安装,Gradle 将尝试从 AdoptOpenJDK 下载一个
如果 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 版本之一中添加。
我们还希望,鉴于此功能对用户的益处,社区 插件作者将在他们自己的任务中利用工具链支持。