Apache Harmony 是 2005 年 5 月宣布的开放源码 Java SE 实现,本文是由 5 部分组成的 进入 Harmony 世界 系列文章的第一篇,这个系列主要介绍 Apache Harmony 项目的内部实现,最新发展现状和开源 Java 开发的模式,并鼓励和欢迎大家参与到 Harmony 的社区中来。本文是 5 个系列的第一篇,概括介绍了 Harmony 项目的背景,技术架构,社区运作和未来的方向。
本文是 5 个系列的第一篇,概括介绍了 Harmony 项目的背景,技术架构,社区运作和未来的方向。
Apache Harmony 的背景
Apache Harmony 的提案在 2005 年 5 月被 Apache 软件基金会(ASF)接受,并且按照 ASF 惯例成为一个孵化器(incubator)项目。
Harmony 为自己定了两个目标,首先是开发出一个独立并且与现有 JDK 兼容的 Java SE 5 实现,并且以 Apache 软件许可证 2.0 版发行;其次是建立一个开放的模块化运行时架构,包括虚拟机和类库之间及其内部的模块化,并通过这个平台,允许社区在此基础上自由定制自己的 Java 实现,或者对某个模块单独进行创新。
Apache Harmony 项目的成立以及它的这两个目标具有很大的现实意义。首先,由于商业JDK的流行性,它们几乎成为事实上的标准,所以 Harmony 必须与它们保持高度的兼容,才能够使应用程序的迁移成本最低,也就相对容易被用户所接受;其次,Harmony 存在的重要意义之一就在于这是一个属于开源社区的 Java 平台,在这个平台上,社区可以自由的移植和创新,而一个开放的模块化的架构,将为移植和创新带来最大的便利性;最后,Apache 软件许可证是一个对商业公司和开源社区都比较友好的开源许可证,因此 Harmony 可以给最大范围的开发人员和用户带来便利。本文和本系列后续文章将详细介绍 Harmony 在兼容性和模块化方面的努力,以及这些目标带来的价值。
也许正是基于以上一些原因,Harmony 项目成立仅仅一年多一点的时间,就得到了广泛的支持和关注,并且得以飞速发展。目前,Apache Harmony 已经拥有了一个活跃的开发社区,并且接受了来自公司,学校和个人的多次捐赠。IBM 在 developerWorks 上提供了一个 Java 虚拟机环境的免费下载,以支持 Harmony 项目的开发,还多次捐赠了核心类库的实现和测试代码,在 IBM 英国 Hursley 软件开发实验室和中国软件开发中心各有一个开发团队积极参与 Harmony 项目。此外 Harmony 项目还接受了三个 Java 虚拟机实现的捐赠,另外还有一个开源 Java 虚拟机 SableVM 正在积极的与 Harmony 社区合作以实现与 Harmony 类库的集成。Java SE 实现难度最大的是其规模庞大的类库,而最近的类库 API 覆盖率统计表明,Harmony 的 J2SE 1.4.2 类库 API 的覆盖率已经超过 80%,Java SE 5 的覆盖率已经达到 79% 以上。目前经不完全测试,在 Harmony 上已经可以良好运行 Eclipse、JEdit、Ant 等流行的 Java 工具,并且可以部分运行 Tomcat 和 Geronimo 等企业应用。
技术架构
如前所述,Apache Harmony 非常注重模块化,从图一中,可以对 Apache Harmony 的总体架构有一个初步的感觉。与所有其他 Java SE 实现类似的是,Harmony 从大体上可以分为三个层次,最下层是操作系统,中间是 Java 虚拟机,最上层是 Java 类库。而 Harmony 的特点在于:
- 虚拟机和类库内部被高度模块化,在 Harmony 中,类库在功能和 Java Package 的基础上被分成 31 个模块,而虚拟机也被分成即时编译器, 内存管理, 线程管理,Java 本地接口等等模块。每个模块都有一定的接口定义,从而有可能单独被替换成不同的实现。
- 操作系统层次与虚拟机层次之间的接口由 Port Layer 定义。Port Layer 封装了不同的操作系统的差异,为虚拟机和类库的本地代码提供了一套统一的 API 访问底层系统调用。
- 虚拟机与类库之间的接口除了 Java 规范定义的 JNI,JVMITI 之外,加入了一层虚拟机接口,主要由内核类(Kernel Class)和本地代码 VMI 组成,实现了虚拟机接口的虚拟机实现都可以使用 Harmony 的类库实现,并且可以被 Harmony 提供的同一个 Java 启动程序启动。
图一 Apache Harmony 技术架构鸟瞰图
本节将分别对 Port Layer,VMI 和 Java 统一启动程序作进一步的介绍。
Apache Harmony Port Layer
Apache Harmony 在操作系统与虚拟机之间定义了一个 Port Layer,Port Layer 是由一个标准 C 的库(Port Library)来实现得,Port Library 与操作系统交互,为虚拟机和类库的本地代码提供了一个平台无关的标准 C 语言 API 访问系统调用。诸如文件 I/O,网络 I/O, 内存操作,信号处理,以及错误处理等等功能,都被纳入 Port Library 的范围。
通过使用 Port Library, 所有(目前还没有做到,但这是设计目标)与操作系统平台相关的内容被封装在一个库里面,虚拟机和类库的其他部分都可以尽可能以平台无关的方式实现出来。这样一来,将 Java SE 的庞大类库和虚拟机代码移植到其他操作系统的工作就可以被快速的开发出来,从而大大提高了可移植性和程序的可维护性。
在 Apache 软件基金会资助的开源项目中,有一个类似的平台无关库叫做 Apache Portable Runtime(APR), 这个项目是从 Apache Http Server 等项目的开发过程中提炼和分离出来的,目前已经比较成熟,它与 Harmony 的 Port Layer 的目标有类似之处,但是也有明显的不同,从而使得目前 APR 还不适合作为 Java 虚拟机和类库的平台无关库实现。在本系列后续文章中会有单独的文章详细介绍 Harmony Port Library 的设计特点,并与 APR 进行比较。
Apache Harmony 虚拟机接口
Apache Harmony 虚拟机接口定义了类库和虚拟机之间的接口,Java 规范已经定义了一些虚拟机的 API,比如 Java 本地接口(JNI), Java 虚拟机工具接口(JVMTI)等,但是 Java 规范并没有定义类库和虚拟机之间的接口。Harmony 为了模块化和可移植性的要求,定义了虚拟机接口(VMI),只要是实现了该接口的虚拟机就是 Harmony 兼容虚拟机,从而可以与 Harmony 的类库实现互操作,并且可以与 Harmony 提供的 Java 启动程序协作。
Apache Harmony 虚拟机接口分为三个部分,一部分是 Java 语言接口,由 23 个内核类(Kernel Class)组成,另一部分是 C 语言接口,由 10 个函数组成,最后一部分就是标准 JNI。
- 内核类的提出是因为少数核心的公共类是与虚拟机密切相关(VM-specific)的,它们都是属于 java.lang,java.lang.ref,java.lang.reflect 和 java.security 等几个核心的包,比如说 java.lang.ClassLoader, java.lang.ref.WeakReference 等。随着 Java 版本的升级,核心类的数量也可能会增加。Harmony 的类库实现为大多数核心类定义了实现模板。VM 的开发人员可以从零开始实现这些核心类,也可以在 Harmony 提供的模板基础上开始开发。
- 虚拟机接口还定义了 VM 必须实现的 10 个 C 函数,用来访问虚拟机和类库共享的数据结构和接口,比如说访问操作系统抽象库(Port Library),虚拟机本地存储空间等。
- 虚拟机的最后一部分就是标准 JNI,它在这里的主要用途是允许从 Java 类库的本地链接库中创建 Java 对象。
应该说虚拟机接口是一个相对宽松的接口,它并不要求对虚拟机和类库特殊的耦合,对垃圾收集,同步和对象的数据结构等等也没有特殊的规定。另外一个著名的开源 Java SE 类库 GNU Classpath 也有类似的虚拟机接口,本系列后续文章将详细介绍 Harmony VMI,并且与 GNU Classpath 比较。
Apache Harmony 启动程序
Apache Harmony 提供了一个启动程序,也就是通常我们用来运行 Java 程序的 java 和 javaw 命令的实现,这个启动程序是个多目标的启动器,可以根据命令行参数启动不同的虚拟机,也可以支持虚拟机特有的选项,如属性文件或命令行参数等。这一切都是基于虚拟机接口,Port Library 和标准 JNI 实现的。
在进一步介绍启动程序之前,需要先介绍一下 Harmony Development Kit(HDK)和 Harmony JRE 的目录结构,请参考图二。HDK 是一个完整的开发包,不仅仅包括 Harmony 用户所需的所有内容,也提供 Harmony 开发人员所有的静态链接库和头文件,使得他们可以在此基础上对其中任何一部分进行修改和重新构建。
- <hdkbase>/jdk/jre, 这个目录包含了标准的 JRE 结构,如 bin 和 lib 目录等。
- <hdkbase>/jdk/include,这个目录包含了标准的 JDK 头文件,如 jni.h 等。
- <hdkbase>/include, 这个目录包含了 Harmony 独有的并且被多个模块共享的头文件
- <hdkbase>/lib, 这个目录包含了编译 Harmony 本地代码所需的静态链接库文件,如在 Windows 平台,就包含了 .lib 文件,而在 Linux 平台,则包含了 .a 文件。
对于启动程序来说,需要特别注意的是 <hdkbase>/jdk/jre/bin 目录,在这里可以包含多个虚拟机实现,每一个实现应该被放在该目录的一个子路径里(比如 vm1, vm2 等),缺省的虚拟机实现在 <hdkbase>/jdk/jre/bin/default 目录,如果不指定特定参数,该虚拟机会被启动程序使用。一般来讲,每个虚拟机实现应该包含虚拟机实现文件和资源文件,尤其是必须有三个部分的虚拟机接口的实现。
图二 HDK 目录结构
在调用启动程序的时候,有两个参数被用来指定启动哪一个虚拟机实现,-vmdir 用来指定虚拟机所在的子目录,-vm 用来指定实现了JNI接口的动态链接库,比如要使用 IBM 提供的 VME,而 VME 放在 vm1 目录下的话,启动程序的命令行就应该像:
java -vmdir:vm1 -vm :clearvm.dll …
|
Harmony 的启动程序在启动时将执行以下任务:
- 生成一个 Port Library 实例并且装载它
- 装载虚拟机本地动态链接库
- 初始化内核类
- 调用 JNI_CreateJavaVM(…), main(…), JarRunner 等
Apache Harmony 类库的模块化
Apache Harmony 将类库分成易于管理的模块,这样做的目的是
- 使 Java 类库的开发工作易于管理,开源社区的参与者可以集中开发他擅长的模块
- 方便模块装配, 用户可以自由选择模块提供者,可以自由替换或者升级任一模块
- 使法律方面的风险易于管理,如果开发人员以前接触过其他 Java SE 实现的代码,他也可以参与以前未接触过的模块开发。
- 方便代码捐献
类库的模块实际上是由一组实现相关的功能的 Java 类和本地程序组成的,目前它们按照包的级别来划分,也就是说不会有两个属于同一个 Java package 的类出现在两个不同的模块里(内核类所在的包除外,但也仅在内核类模块和另一个类库模块中出现)。这些模块可以包含私有的内部实现,但是必须导出 Java API 参考文档规定标准 API,也可以导出 Harmony 独有的 API,但是这些 API 并不鼓励用户使用,只是供其他模块调用的。
模块的鉴别方法是: 首先根据 Java 规范,确定各 Java 包之间的依赖关系;然后寻找弱耦合的部分,将本身内聚的包组织在一起,最后在社区讨论哪部分类库应该可以拆开独立成一个模块。目前 Harmony 将 Java SE 5 规定的类库分成了三十一个模块,在 Java 升级之后,模块的数量可能会增加。目前这三十一个模块包括:
- ACCESSIBILITY
- ANNOTATION
- APPLET
- ARCHIVE
- AUTH
- AWT
- BEANS
- CONCURRENT
- CRYPTO
- IMAGEIO
- INSTRUMENT
- JMX
- JNDI
- LANG-MANAGEMENT
- LOGGING
- LUNI (lang, util, net, io)
- MATH
- NIO-CHANNELS
- NIO-CHARSET
- ORB
- PREFS
- PRINT
- REGEX
- RMI
- SECURITY
- SOUND
- SQL
- SWING
- TEXT
- X-NET
- XML
在 Harmony 的代码资源库中,每个模块的源文件都保存在自己的各自的路径中,如果使用 Eclipse 做开发工具,每个模块就可以看作一个单独的工程项目。特别需要注意的是,按照 jar 文件的规范,在每个模块都有一个 META-INF/manifest.mf 文件,在这个文件中定义了该模块的 OSGI 元数据,其中最重要的就是该模块导入导出的 Java package。
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Harmony NIO
Bundle-SymbolicName: org.apache.harmony.nio
Bundle-Version: 1.0.0
Bundle-ClassPath: .
Eclipse-JREBundle: true
Import-Package: java.io,
java.lang,
java.lang.ref,
java.lang.reflect,
java.net,
java.nio.charset,
java.security,
java.util,
org.apache.harmony.kernel.vm,
org.apache.harmony.luni.net,
org.apache.harmony.luni.platform,
org.apache.harmony.luni.util,
tests.support;hy_usage=test;resolution:=optional,
tests.util;hy_usage=test;resolution:=optional
Export-Package: java.nio,
java.nio.channels,
java.nio.channels.spi,
org.apache.harmony.nio
|
在编译之后,每一个模块将被打包成一个 jar 文件,如果该模块有本地代码,则该模块的本地代码被编译成一个单独的动态链接库文件。如图二所示,hyluni.dll 就是 LUNI(lang, util, net, io)模块的本地二进制代码库,而在 <hdkbase>/jdk/jre/lib/boot 目录中,对应 LUNI 模块的则有一个 luni.jar。
Apache Harmony 的开发方法
近年来,开源软件相关的知识产权问题越来越受到关注。为了保证对知识产权的尊重,保持 Harmony 代码的纯洁性和原创性,除了 Apache 软件基金会原有的通用规则之外,Harmony 开发社区花了很大的精力来定义 Harmony 接受代码捐赠和接受项目参与者的规则。
Harmony 要求每个开发人员在参与代码捐赠之前,必须完成一个问卷调查,问卷的主要内容是关于该开发人员以前是否接触过其他 Java SE 实现,如果他接触过其他专有代码的某一部分,他就不能参与 Harmony 相应模块的代码工作(但也有一些特殊的例外情况)。同时,任何现有代码的捐赠必须提供代码的"血统"信息。
知识产权之外的另一个重要问题就是兼容性。Harmony 的目标产生一个 Java SE 5 兼容的实现,它不仅仅要完全遵循 Java API 参考定义的 Java SE 规范,Java 语言规范以及 Java 虚拟机规范;同时还必须保证与现有 Java SE 参考实现的兼容性,为此,Harmony 采用了测试驱动开发模式,以单元测试用例来保证 Harmony 的行为和参考实现一致。最重要的是,Harmony 正在试图申请 Java SE 5 JCK 兼容性测试的许可证,因为只有被 JCK 认证过,Harmony 才能正式被称为 Java 兼容的实现。
除了单元测试之外,Harmony 还会通过一些已有的成熟的 Java 程序来作为黑盒测试的应用,测试 Harmony 是否已经可以支持这些应用。目前 Harmony 可以运行 Eclipse,Tomcat,JEdit 等 Java 程序。Harmony 提供了一个工具,鼓励 Java 程序作者将他们的程序运行在 Harmony 上,并且通过这个工具将运行结果反馈给 Harmony 开发社区。
总的来说,Harmony 采用以下几种方式来衡量开发进度:
- 粗粒度层次上,可以衡量一个模块是否已经开发。
- 使用工具比较 Harmony 和参考实现兼容性,比如使用 JAPI 检测 Harmony 的 API 覆盖率。
- 使用工具检查测试覆盖率,检查 Harmony 的各种行为是否得到充分的测试。
- 支持成熟的 Java 应用程序列表。
- 将来的目标是通过 JCK 测试。
本系列后续文章将进一步介绍 Harmony 开发中的最佳实践。
Apache Harmony 未来的发展方向
Harmony 的一个重要目标是类库的模块化。Harmony 将进一步采用 OSGi 运行时框架技术,根据模块元数据描述,自动装载模块。并且还将努力实现以下目标:
- 允许同时装载同一模块的不同版本。
- 通过模块的 MANIFEST.MF 元数据文件控制其所包含的 Java package 的可见性。
- Java 类和相应的本地代码的启动/停止/卸载等生命周期管理。
你能为 Harmony 做些什么
目前 Harmony 已经建立了一个相当活跃的开发社区,并且非常欢迎更多的人参与进来,包括参与 Harmony 的开发,移植 Harmony 到其他平台(目前 Harmony 只有 IA32 的 Windows 和 Linux 版本),撰写文档,在 Harmony 上运行成熟的 Java 应用检查其实现的覆盖率和兼容性等等。除此之外,同样重要的是,你还可以参与远未成熟的 Harmony 用户社区,试用 Harmony,参与 Harmony 的讨论,等等。Harmony 是一个属于所有人的 Java 平台。
总结
- Harmony 的目标是一个完全兼容的开源的 JSE 实现
- Harmony 投入巨大的努力保证知识产权的纯洁性
- Harmony 社区的目标是创建一个一流的模块化的运行时环境
- Harmony 在过去的一年中取得了巨大的成就
- Harmony 欢迎任何有兴趣的开发者
转载自 ibm dw http://www.ibm.com/developerworks/cn/java/j-lo-harmony1/