这篇文章概述了Gradle对Java 9的支持,涉及到运行时、交叉编译、MRJARs和Jigsaw模块支持。自从上个月Java 9发布以来,我们收到了很多问题,并决定在这里进行解答。
从4.2.1版开始,Gradle支持什么?
从Gradle 4.2.1开始,完全支持使用JDK 9的主要发行版(如Oracle JDK9、OpenJDK9和Azul JDK9)构建和运行Java应用程序。此外,还支持交叉编译(由JDK9构建但在JDK8上运行)。
在升级到Java 9时,无论使用何种构建工具,有些构建都会出现问题。Java团队对JDK进行了良好和必要的修改,以促进更好的软件架构和安全性,但这意味着取消对一些API的访问。即使你的项目已经准备好了,一些工具和Gradle插件还没有被更新以适应Java 9。
目前还没有消费和组装多版本JAR的便利方法,但如果你渴望使用它们,可以看看这个MRJAR-gradle的例子。
Java模块,又称Jigsaw Support
如果你还不熟悉Java 9平台的模块系统,也称为Project Jigsaw,你应该阅读Project Jigsaw。模块系统快速入门指南。模块系统的现状》中对其动机和术语进行了很好的解释。
一个模块被定义为 "一个命名的、自我描述的代码和数据的集合",其中包被视为代码边界,并被明确地导出和要求。非出口的包对于模块消费者来说是不可见的,而且两个模块不能出口相同的包,也不能有相同的内部包。这意味着包不能被 "分割 "或在多个模块之间重复,否则编译会失败。
这里有一份指南,展示了今天如何用Gradle来使用Java模块。它引导你完成必要的步骤,告诉Gradle在编译Java源和补丁模块时使用modulepath ,而不是classpath ,以达到测试目的。
如果你想逐步转换到Java 9模块,建议采用自下而上的方法(先转换没有依赖关系的库)。毕竟,模块是可以像普通JAR一样消耗的。当 "传统的 "JARs被添加到modulepath ,要注意自动模块。
用Java库插件实现封装
Java 9模块系统的2个主要目标之一是通过强封装提供更好的软件架构。Gradle 3.4引入了Java Library Plugin,它通过分离api (那些要暴露给消费者的)和implementation (其内部不会泄露给消费者)的依赖关系来实现对库的强封装。
当然,这并不排除使用Java classpaths,这是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模块,你可以使用这个粗糙的映射:
implementationdependency => 模块声明requiresapi依赖性 => 模块声明requires transitiveruntimeOnly依赖性 => 模块声明requires static
接下来的步骤
请继续关注Gradle中对第一类Java模块支持的更新。
你可以使用《构建Java 9模块》指南来学习如何使用Gradle的Java模块。