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/