在Fedora的發布版中Fedora是首個包含了大量用Java編程語言編寫的代碼的版本正是由於GNU類路徑(Classpath)和GNU gcj(GNU Compiler for Java)的改進才促成了這些附加部分
GCJ基礎
首先GNU gcj不是Java
然而gcj的目標是實現一個完整的系統該系統兼容於Java並且將預編譯器(aheadoftime compiler)置於中心它擁有一個基於GNU類路徑的淨化類庫和一個內置的解釋器其編譯器可以將Java源文件類文件甚至是整個jar文件編譯成目標碼
以前gcj對待Java采取的是一種激進且傳統的方式它認為Java好像是C++的某個不常用的方言似的這麼做有好的一面然而不幸的是兩者運行時的鏈接模型差異太大——因此當遇到一些規模比較大復雜度比較高的Java應用時這種方法就無能為力了特別是面對那些有著復雜的類加載機制的Java應用時顯得尤為突出
在GCC的發布版中我們對gcj實現了一種新的編譯方式稱之為二進制兼容性ABI(Binary Compatibility Application Binary Interface)這種編譯方式將所有的鏈接推遲到運行時刻進行並且完全實現了Java的二進制兼容規范——正好是讓預編譯的代碼與類裝載結合所需要的
我們還增加了一個類映射數據庫在運行時只要我們定義好一個類gcj運行時(叫做libgcj)就會在數據庫中尋找這個類如果找到該類(注意我們這裡使用的是類的內容而不僅僅是類名)那麼libgcj就會映射到該共享庫中該庫包含了編譯後的類
這兩個改變使得我們可以做一些更強大的事情我們可以預編譯Java程序而不必要求任何應用級的改變此外由於采用了新的方式對字節碼進行校驗我們還能確保編譯的代碼在運行時的類型安全
構建RPM
在Fedora Core上構建Java應用是很簡單的——現存的構建方式不會發生變化Fedora Core舶來了Ant並且使用來自Eclipse的Java編譯器將Java代碼編譯成字節碼
描述如何編寫RPM已經超出了本文討論的范圍但是Fedora RPM指南上有一些有用的信息JPackage上也有一些Java特定的指南
一旦你的程序被編譯成字節碼你就可以將他們編譯為本地代碼因為gcj尚不包含一個即時編譯器(JIT)這就是其獲得合理性能的方法在某些情況下其性能可能會超過已有即時編譯器因為gcj使用了共享庫……當你同時運行應用程序的多個實例時你就會看到這種巨大的差異
Fedora提供了兩個程序使得本地編譯包的工作變得更簡單我們在構建RPM時會使用到他們
第一個程序是aotcompilerpm它會搜索jar文件並且使用gcj將他們編譯到共享庫中aotcompilerpm知道一些gcj特定的技巧例如在編譯前將比較大的jar文件分割為若干個小的文件(在運行時編譯一個大的jar文件將耗費大量內存資源)在鏈接結果共享庫時使用–Bsymbolic(這會導致運行時性能改善)
假如你沒有在構建RPM那麼一個替代方案就是直接將程序中的jar文件編譯到共享庫中這裡我展示一個最簡單的方法(我之前提到過對於一個大的jar文件這樣做會非常慢)
gcj fjni findirectdispatch fPIC shared \
WlBsymbolic o foojarso
foojar
分解一下
◆fjni告訴gcj在Java代碼中的本地方法(native methods)是用JNI實現的
◆findirectdispatch告訴gcj使用二進制兼容性ABI(Application Binary Interface)
◆當構建一個共享庫時我們需要使用fPIC和shared
◆WI和Bsymbolic告訴鏈接器在可能的情況下綁定共享庫中的引用
Fedora Core提供的第二個有用的程序是rebuildgcjdb當安裝或者卸載一個RPM改變了全局類映射數據庫時我們將使用該程序並且該程序應該運行在RPM的%post和%postun部分
rebuildgcjdb根據約定來運轉——它假設每個包在目錄/usr/lib/gcj(對於多架構操作系統中位的包目錄為/usr/lib/gcj有相應的RPM宏去解決這個問題)下的某個地方安裝自己的類映射數據庫然後它循環遍歷所有的這些個體數據庫並且把他們整合到運行時使用的全局數據庫中
注意到使用gcj去編譯一個Java程序並不總是能成功的Gcj的類庫尚不完整有時程序會使用到某些尚未實現的API例如Swing目前仍在積極開發中同樣盡管Sun公司已經發布了警告一些包使用了私有的comsun*或者sun*下的APIs——然而一般來說gcj並沒有實現他們
誰在使用?
Fedora Core 使用了gcj來為很多應用程序進行編譯
◆首先Fedora包含了ant以及ant的很多依賴以此來編譯和運行其他Java程序它也包含了Eclipse的Java編譯器
◆Tomcat及其依賴
◆OpenOffice中的Java代碼
◆Eclipse IDE和一些插件比如CDT
Fedora中的新面孔
◆RSSOwl一個RSS閱讀器
◆Azureus 一個強大的BitTorrent客戶端
◆Frysk 一個用來監控運行的進程或線程的執行分析技術
JOnAS應用服務器一個JEE實現也在進行中但是它還尚未通過Fedora Extras的審查
接下來的工作
在過去的一年中GNU Classpath社區向著目標大踏步地前進我們期望在年能繼續保持這個勢頭我們有一個經常更新的API比較頁面你可以在這裡追蹤我們API的狀態
我們也在為gcj的核心改進而努力工作著將編譯器運行時和類庫更新到Java
最後我們正在libgcj裡實現Java的安全架構這會實現一個Mozilla的插件和netx(Java Web Start的一個實現)
個人簡介
Tom Tromey於年畢業於加利福尼亞理工學院現主要從事Red Hat下的GNU Java編譯器和運行時開發工作他編寫了GNU Automake
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25726.html