大约一年前,Mark Reinhold(Sun/Oracle的顶级Java工程师之一)在JavaONE上宣布了“类路径已死!”的言论,并伴随一系列如这篇博客的文章,宣称Java的未来将是模块化的。与此同时,JDK 7的时间表发生了巨大变化,我们可能要到2012年或更晚才能在Java中看到模块。在此期间,JSR 294团队停滞不前,开始,然后再次停滞,缓缓地向一个紧密集成的Java模块化标准迈进,可能需要重大语言、字节码和打包方式的改变来支持。
我一直认为,引入一个坚实、实用的模块化标准不需要这么多。作为我们的JBoss AS 7概念验证工作的一部分,我们已经通过创建JBoss Modules证明了这一点。
模块里有什么?
如果你没有关注JDK 7的发展,你可能甚至不知道你错过了什么。
一个模块是指任何类和资源的集合,与单个类加载器相关联。模块可以表达对其他模块的依赖。从这些依赖中导出的类和资源对依赖模块中的类是可见的。可见性是来自一个类加载器的类“看到”另一个类加载器的类的能力。要导出一个类或资源,就是使这样的类或资源对依赖者可见。
所以,模块化系统提供了一种将类和资源打包成模块的方式,并在运行时建立类加载器图,以便满足所有表达出的依赖。
模块有什么好处?
在Java中运行应用程序的传统方法使用了众所周知的 类路径
机制。这基本上创建了一个包含所有JAR资源拼接在一起的单一应用程序类加载器。
现在想象一下,你有一个非常大且复杂的应用程序,包含数十个JAR文件。想象一下,其中一些JAR文件并非总是被使用,或者由于冲突的依赖关系,一些JAR文件代表了同一类和包的多个、冲突的版本。这个问题以及其他类似的问题,通常被称为 JAR地狱。
模块可以大大缓解这个问题。当所有JAR文件都捆绑为模块时,一个JAR文件将永远不会“看到”依赖类的冲突版本,或者无意中从其他JAR文件中获取资源。此外,如果一个模块从未被使用过,那么它将永远不会被加载,这可以提高大型应用程序的启动时间。
为何还要等待?
JBoss Modules是Java 6及以上版本的一个独立模块系统。它支持以下功能(及更多)
- 一个内存高效、高性能、并发/线程安全的代理类加载器实现,能够在O(1)时间内加载任何类或资源
- 一个可扩展的模块加载器系统,允许用户插入替代的模块定义/加载策略
- 一个易于使用的捆绑本地模块加载器,以简单、可预测的结构从文件系统中加载模块(打包为标准JAR文件或展开目录)(想想Maven,但更简单)
- 一个简单的启动过程(见下文)
- 一个有用的 运行时API,用于加载模块、获取模块的类加载器、在运行时创建模块、扩展 JDK服务加载器机制 以使其了解模块,等等
- 平台特定原生代码的管理
模块化程序是这样启动的
java -jar jboss-modules.jar -mp path/to/modules my.main.module.name
在你的模块路径(-mp
)中,你指定默认模块加载器将搜索的根目录(或目录)。一个模块使用简单的XML描述符来定义,如下所示
<module xmlns="urn:jboss:module:1.0" name="org.jboss.msc"> <main-class name="org.jboss.msc.Version"/> <resources> <resource-root path="jboss-msc-1.0.0.Beta3.jar"/> </resources> <dependencies> <module name="org.jboss.logging"/> <!-- Optional deps --> <module name="javax.inject.api" optional="true"/> <module name="org.jboss.threads" optional="true"/> <module name="org.jboss.vfs" optional="true"/> </dependencies> </module>
这个描述符格式的完整模式包含在jboss-modules.jar中,因此与您喜欢的IDE集成很容易。还有许多可用的扩展功能,允许您紧密控制导出或导入的包,您还可以选择性地排除资源JAR文件中的内容(使使用预包装JAR文件更加容易)。
这与JSR 294有何不同?
这个简单的模块系统与目前的JSR 294相比有几个优点。
- 它现在就可以使用。无法预测JDK模块将在何时可用——可能在2012年的Java 7中,可能在Java 8或之后。这是一个您现在就可以使用并贡献的项目。
- 不需要侵入式语言、字节码或编译器更改,也不需要JCP批准。
- 就目前情况来看,JBoss Modules 应该 与JSR 294兼容,如果Jigsaw巩固并成为OpenJDK的一部分,我们将努力保持兼容性。
这与OSGi有何不同?
- 它要简单得多;只需要一个JAR文件就可以启动您的模块化应用程序。
- 它更简洁:没有服务层或任何其他OSGi提供的高级功能。它只做一件事,而且做得很好。
- 同时,它非常强大,可能成为OSGi实现可以使用的类加载框架的基础(未来将详细介绍,请保持关注!)。
当前状态如何?
JBoss 模块现在可以通过 Maven 获得,地址为 org.jboss.modules:jboss-modules。同时还有一个 JIRA 实例 用于报告问题。有关 AS 7 中模块的讨论可以在 此处 进行,或者在 FreeNode IRC 的 #jboss-msc 频道进行(通过 WebChat 加入,使用您的 注册昵称)。源代码托管在 GitHub。
那么,你还在等什么呢?