Gradle Java 9 支持现状
引言
本文概述了 Gradle 对 Java 9 的支持,涉及运行时、交叉编译、MRJARs 和 Jigsaw 模块支持。自上个月 Java 9 发布以来,我们收到了许多问题,因此决定在此集中回答。
Gradle 4.2.1 版本支持什么 #
截至 Gradle 4.2.1,使用 JDK 9 的主要发行版(如 Oracle JDK9、OpenJDK9 和 Azul JDK9)构建和运行 Java 应用程序已得到全面支持。此外,交叉编译(由 JDK9 构建但在 JDK8 上运行)也已得到支持。
无论使用哪种构建工具,升级到 Java 9 时,一些构建将会中断。Java 团队对 JDK 进行了良好且必要的更改,以促进更好的软件架构和安全性,但这意味着删除了对某些 API 的访问。即使您的项目已准备就绪,某些工具和 Gradle 插件尚未更新以与 Java 9 配合使用。
目前还没有方便的方法来使用和组装多版本 JAR(Multi-Release JARs),但如果您希望使用它们,可以查看这个MRJAR-gradle 示例。
Java 模块,又称 Jigsaw 支持 #
如果您还不熟悉 Java 9 平台模块系统(也称为 Project Jigsaw),您应该阅读Project Jigsaw: 模块系统快速入门指南。其动机和术语在模块系统现状中得到了很好的解释。
模块被定义为“命名的、自描述的代码和数据集合”,其中包被视为代码边界,并且被明确地*导出*和*要求*。未导出的包对模块消费者不可见,并且两个模块不能导出相同的包,也不能拥有相同的内部包。这意味着包不能在多个模块之间“拆分”或重复,否则编译将失败。
这里有一个指南,展示了如何立即使用 Gradle 的 Java 模块。它会引导您完成必要的步骤,以告诉 Gradle 在编译 Java 源代码和修补模块以进行测试时使用 modulepath
而不是 classpath
。
如果您希望逐步转换为 Java 9 模块,建议采用自下而上的方法(首先转换没有依赖项的库)。毕竟,模块可以作为常规 JAR 使用。当“遗留”JAR 被添加到 modulepath
时,请注意自动模块。
使用 Java 库插件实现封装 #
Java 9 模块系统的两大主要目标之一是通过强封装提供更好的软件架构。Gradle 3.4 引入了Java 库插件,该插件通过将 api
依赖项(旨在暴露给消费者)与 implementation
依赖项(其内部不会泄露给消费者)分离,从而强制对库进行强封装。
当然,这并不能消除 Java 类路径的使用,正如Java 模块的另一个目标所述。您可以在这篇文章中了解 Java 库插件的动机和用法。值得注意的是,Java 库插件对使用 Java 7 及更高版本的项目很有用——您无需迁移到 Java 9 即可拥有更强的封装性。
以下是这个示例库在实践中的含义
apply plugin: 'java-library'
name = 'mylibrary'
group = 'com.mycompany'
dependencies {
api project(':model')
implementation 'com.google.guava:guava:18.0'
}
我们假设有一个应用程序使用 mylibrary
。
public class MyApplication {
public static void main(String... args) {
// This does not compile using 'java-library' plugin
Set<String> strings = com.google.common.collect.ImmutableSet.of("Hello", "Goodbye");
// This compiles and runs
Foo foo = com.mycompany.model.internal.Foo();
// This also compiles and runs
Class clazz = MyApplication.class.getClassLoader().loadClass("com.mycompany.model.internal.Foo");
Foo foo = (Foo) clazz.getConstructor().newInstance();
}
}
您可以看到,通过采用 Gradle 的 Java 库插件,您可以获得一些好处。如果您迁移到 Java 模块,可以使用这个大致的映射
implementation
依赖项 =>requires
模块声明api
依赖项 =>requires transitive
模块声明runtimeOnly
依赖项 =>requires static
模块声明
后续步骤 #
敬请关注 Gradle 中一流 Java 模块支持的更新。
您可以使用构建 Java 9 模块指南来学习如何立即使用 Gradle 的 Java 模块。