标准 Java 模块系统的需求

  • Alex Blewitt
  • 王丽娟

2011 年 6 月 12 日

话题:Java语言 & 开发架构

Mark Reinhold 前些天公布了 Java 模块化的第一份公开草案。正如Mark 在有关这个问题的博客里说的,这次关于 Java 模块化的讨论和先前的 JSR294 迭代有所不同,这次讨论不是 Sun/Oracle 关起门来进行的,而是引入了参与 OpenJDK 的其他成员,比如 IBM,还有 Java SE 和 Java EE 社区的其他成员。

由于这只是一份草案,有些问题仍然需要商讨,但它已经对什么是 Java 模块化进行了统一的定义。有 IBM 的参与,这份草案比以往更加关注与 OSGi 之间的互操作性。

有个比较有意思的需求是,即便ServiceLoaderResourceBundle在 Java 模块化里的表现并不尽如人意,但模块化还是想基于这两部分内容构建,以便那些想用标准模式的开发人员不用关注细节就可以利用模块化。目前,ServiceLoader 在处理多个类加载器的时候还有问题

让 JVM 模块化的主要目的之一是对 JVM 库进行分割,JVM 库这些年已经增长到了几十兆。(不处理模块化概念的 Scala 也已经有十兆了)。不过 JVM 库里所有的类都在同一个类加载器里;而 OSGi 是每个 Bundle 有一个类加载器,这就不能进行直接的映射。(OSGi 有片段的概念,片段能把自己写到父类加载器里去)。文档里有一部分需求定义到,要支持有单独类加载器的模块系统和提供多个类加载器方法的模块系统。

文档里有些描述还比较模糊。比如说,要求版本完全有序,但似乎还没有像Semantic Versioning这样一致的版本化方法。此外,文档要求严格定义元数据(版本号是其中一部分),而版本的概念还有待商榷。

另一个悬而未决的问题是,模块信息是否应该像编译好的 Java 代码或可声明的外部库那样使用。OSGi 利用已有的 MANIFEST.MF 文件处理编码依赖,先前的 Jigsaw 实现则编译一个 Java 类文件,允许通过库进行内省。这对 Java 变种有一个不利影响,就是 Mirah 或 JRuby 等非 Java 语言使用模块系统会更加困难。

这个需求貌似还有较大争议。虽然 JRuby 的领导者 Charles Nutter 说他还没来得及阅读完整的规范,但他在Reinhold 的博客里评论说

Jigsaw 模块化系统要求有一个可能包含注解的.class 文件,因此也没必要限制参与语言:
  • 发布前要先编译成 JVM 字节码
  • 支持全部的 Java 语言结构,比如源码级的注解

换句话说,JRuby、JavaScript(Rhino)、各个版本的 Smalltalk、Python(Rhino)及其它几种语言会立即被排除在外了。

提案还谈到了通用打包系统(比如 rpm 和 easy_install),借助这类系统可以把 Java 运行时传递给其他系统和已在网络上发布的工件。和模块化相比,对这部分的论述要稍微深入一点儿。

这份提案虽然尚未完成、还有待解决的问题,但已经收到了一些积极的反馈

文档里还有很多很多好的需求,这些需求要是都能以开放和兼容的方式实现,Java 一定会从中获益。

另一个好处是,一旦模块化成为 Java SE 8 的一部分,向 OSGi 转会比现在容易得多。现在要想把已有系统往 OSGi 上迁移,最大的障碍往往是系统的模块化,因为系统最初就不是以模块的方式构建的。这不是 OSGi 本身的问题,而是模块化概念的问题。你要是有非模块化的代码,就很难对它们进行模块化。在 Java SE 8 里,这个问题会在开发周期的更早期出现,这有助于开发人员从一开始就用模块的方式去设计系统。如果基本的 JVM 模块系统不能满足你的需求,你可以把已有的 Java SE 8 模块转到 OSGi 上,这些模块还会按原来的样子运行,所以迁移变得轻而易举。然后你就可以利用 OSGi 的优势对模块进行增强了(见下文)。

Java 的模块化可能会使OSGi-lite模式成为现实,会鼓励 Java 库的开发人员使用模块元数据对他们的运行时进行注解,而这些元数据都能被 OSGi 运行时使用。在任何情况下,就算有一些已知的分歧,只要用一种兼容而合理的方式前进,对所有 Java(和基于 Java)的开发人员就都有好处。

你怎么看提出的这些模块化需求呢?

查看英文原文:Requirements of a Standard Java Module System

Java语言 & 开发架构