Jigsaw 蓄势待发

阅读数:1495 2009 年 7 月 6 日

话题:Java语言 & 开发架构

Java 7 有三个主要目标。首先是通过 Jigsaw 项目模块化 Java 平台。第二是通过 invokeDynamic 指令和达芬奇机项目将 JVM 发展为多语言平台,第三是通过项目Coin来解决 Java 程序员面对的一些常见生产效率问题。

将 Java 平台模块化带来了许多好处:通过消除 JDK 里众多类之间日益增长的相互依赖而改善了性能;由于允许下载 JDK 的子集而不是一次下载整个平台,减少了下载量;允许在内存有限的设备如嵌入式控制器上安装 JRE 的一个子集。

Sun 公司正在采取双管齐下的办法来构建 JDK7 的模块化特性:JSR 294 和 Jigsaw。JSR 294 的主要目的是提高编译时和运行时环境之间的逼真度(fidelity)。这将增加语言功能来支持 Java 的模块系统,并更新目前需要类路径信息的重要组成部分,如 javac 和 JVM 本身。JSR 294 最终将取消类路径。因为它独立于 Jigsaw ,所以也可用于其他模块化系统,如 OSGi ,甚至可以用于其他处理依赖关系的工具如谷歌的 Guice 或未来版本的 JSR 299(Java 的上下文和依赖注入) 。

Jigsaw 将使用给 JSR 294 开发的部分特性,为 Sun 的 JDK7 实现构建模块系统。它是 Sun JVM 的一个实现细节 ,不会成为 JSR 的一个标准,而且技术上也不属于 Java SE 。令人惊讶的是,Jigsaw 与它打算取代的类路径,尽管是 Java 主机系统的事实标准,但都不属于 Java 语言规范。Sun 已经创建了 OpenJDK 的一个开源子项目 ,也称为 Jigsaw。该子项目将拥有 JSR 294 参考实现以及 Jigsaw 模块系统的设计与实现。

Alex Buckley在今年的 JavaOne 大会演讲上提供了一些 JSR 294 和 Jigsaw 如何工作的技术细节。其主要特征是引入了一个标准模块信息接口,Java 程序可以使用它来指定依赖和其他细节。详细信息包括模块 id,应用程序的主类,程序提供的模块和所依赖的模块。详细信息中还可包括版本信息(可选的),这会让 Sun 和开发者在将来易于修改已经被广泛使用的类库和 API。一个来自 Buckley 的幻灯片的例子:

module org.planetjdk.aggregator @ 1.0 {

    system jigsaw;

    requires module jdom @ 1.*;

    requires module tagsoup @ 1.2.*;

    requires module rome @ =1.0;

    requires module rome-fetcher @ =1.0;

    requires module joda-time @ [1.6,2.0);

    requires module java-xml @ 7.*;

    requires module java-base @ 7.*;

    class org.planetjdk.aggregator.Main;

}

 

使用此模块信息,Jigsaw 的打包工具(jpkg)能够创建一个映射部署文件,可以根据不同的平台而变化而且更紧密的与平台的能力相结合。这样 Jigsaw 将使得 Java 桌面应用在 sun 支持的各个平台上更加接近一等公民, 这是 Sun 振兴桌面 Java 所做努力的一个关键步骤。Mark Reinhold 在 JavaOne 会议上演示了 Jigsaw 目前的一些能力,使用 Linux 的 Synaptic Package Manager 为一个简单的应用逐步建立需求,从一个基础的 Java 模块开始逐步增加额外的模块,如 AWT 和 Swing 。

Sun 决定兴建 Jigsaw 而不是使用现有的模块系统例如 OSGi 是非常有争议的, Sun 并没有清楚的阐明为什么它已决定走这条路。在最近 Java Posse 的一个podcast中,Mark Reinhold 和 Alex Buckley 也提供了一些关于两者分歧的技术细节,阐明了为什么 Sun 公司决定建立自己的系统。除了如同 OSGi 那样将打包的应用更多的绑定于平台之上,两个系统的依赖模型是不同的。Sun 公司需要能够将包劈成不同的模块并将在运行时把它们加载到相同的类加载器中——例如 java.util 包可能被劈成不同的模块(甚至对有内存限制的装置有不同的实现)。为了支持这一特性 Jigsaw 有一个本地依赖的概念,该概念是递归的。所以,如果模块‘Swing’对于 AWT 有本地依赖而模块‘AWT’对于模块‘base’有一个本地依赖 ,那么在运行时模块 Swing、AWT 和 base 都将在同一类装载器中加载。虽然在 OSG 中的片段(frament)也是类似的概念,但不够更灵活,片段自己无法表达依赖性。

企业专家小组联席主席 Eric Newcomer 对此仍持怀疑态度。在最近的博客中,他把 Jigsaw 描述为“Sun 重新发明 OSGi 的最新尝试,或在任何情况下阻挠 OSGi 或者建立他们能控制的 OSGi 替代品”,他继续写道:

“我今年没有参加 JavaOne 大会,所以可能由于我没有亲临而有错误的印象,但我的理解是,项目 Jigsaw 没有提到 OSGi 。Java 7 的计划说明也没有提到。因此,对于 Jigsaw 项目是否是对 Java 模块化的一个威胁这个问题,我的答案是,是的。”

其他一些博客被 Sun 的努力所打动,给出了积极的响应。其中Bram Bruneel对本地包生成留下了深刻的印象:

..Mark 向我们展示了一个在 Ubuntu 上打包和分发 Java 应用的不错的演示 。JDK 模块将会是标准的 Debian 软件包,您将能够创建自己的 Java 应用程序,导出为 Debian 软件包,并确定运行您的应用程序所需要的 Java 模块依赖。”

Alex Miller在他的文章中对 Jigsaw 的推崇是有见地的:

“项目目标是雄心勃勃的——在演示中有一个相当清晰的愿景,比我以前理解的要宽广得多。这个愿景包括对于我们如何编译、封装、启动我们的 Java 应用程序的全新方案。”

Glyn Normington听了 Java Posse 的 podcast 并写了评论:

“很高兴看到新出现的一些技术细节,我开始明白为什么 OpenJDK 选择与 Apache 的 Harmony 不同的模块化方案。”

Dalibor Topic对于本地打包工具的潜能特别感兴趣:

“语言概念的模块与实际模块系统的分离,可以让我们使用类似 jpkg 的工具来创建一个抽象模块到实际部署文件的 N:M 映射。为特定平台自由挑选其最好的发布机制有明显的好处,例如,在有一个软件包管理器的平台上,最友好的 JDK 发布方式是通过相应的软件包来发布。不用花大力气,通过提前编译转为平台所需要的本地化代码也成为可能:这一工作被转化为(在模块被封装为部署文件之前)可以应用于模块的另一个后期处理步骤,如在当前的 jpkg 代码中的 pack200 和 LZMA 压缩。将一个模块透明的分割为几个本地部署文件也变得很容易实现,例如,JNI 库也可以转化为几个独立的、特定于架构的包,这样对于拥有多个架构本地代码的复杂应用,减少了下载量(顺便说一下,就像 JDK 一样);同样,发布一个非常小的更新包来替换本地代码中一段有缓冲区溢出问题的代码片段也变得非常容易。”

查看英文原文:Jigsaw Falling Into Place