Gradle Java 9 支持状态
简介
这篇文章概述了 Gradle 对 Java 9 的支持,涉及运行时、交叉编译、MRJAR 和 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 一起使用。
目前没有用于消费和组装 Multi-Release JAR 的便捷方法,但如果您想使用它们,可以查看这个 MRJAR-gradle example。
Java 模块 (又名 Jigsaw 支持) #
如果您还不熟悉 Java 9 平台模块系统(也称为 Project Jigsaw),您应该阅读 Project Jigsaw: Module System Quick-Start Guide。《模块系统状态》中很好地解释了动机和术语。
模块被定义为“代码和数据的命名、自描述集合”,其中包被视为代码边界,并被显式导出和需要。未导出的包对模块消费者不可见,并且 2 个模块不能导出相同的包,也不能具有相同的内部包。这意味着包不能在多个模块之间“拆分”或重复,否则编译将失败。
这里有一个指南,展示了今天如何将 Java 模块与 Gradle 一起使用。它将引导您完成必要的步骤,以告知 Gradle 在编译 Java 源代码和为测试目的修补模块时使用 modulepath
而不是 classpath
。
如果您希望逐步转换为 Java 9 模块,建议采用自下而上的方法(首先转换没有依赖项的库)。毕竟,模块可以作为常规 JAR 消费。请注意将“传统”JAR 添加到 modulepath
时的自动模块。
使用 Java Library Plugin 实现封装 #
Java 9 模块系统的两个主要目标之一是通过强封装提供更好的软件架构。Gradle 3.4 引入了 Java Library Plugin,它通过将 api
依赖项(旨在向消费者公开的依赖项)与 implementation
依赖项(其内部结构不会泄漏给消费者)分开,从而为库强制执行强封装。
当然,这并没有消除 Java 类路径的使用,正如Java 模块的另一个目标中所述。您可以在这篇文章中了解 Java Library Plugin 的动机和用法。值得注意的是,Java Library Plugin 对于使用 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 Library 插件,您可以获得一些好处。如果您要迁移到 Java 模块,可以使用以下粗略映射
implementation
dependency =>requires
module declarationapi
dependency =>requires transitive
module declarationruntimeOnly
dependency =>requires static
module declaration
下一步 #
请继续关注 Gradle 中关于一流 Java 模块支持的更新。
您可以使用构建 Java 9 模块指南来了解今天如何将 Java 模块与 Gradle 一起使用。