Fedora Core 4はJavaプログラミング言語で書かれた相当量のコードを含む最初のFedoraリリースです。これらの追加はGNU ClasspathとGNU gcjの改良によって可能になりました。
GCJの基礎
最初に、GNU gcjはJavaではありません。
それでも、AOT(Ahead-of-Time)コンパイラを中心に、Javaと互換性のある、完全なシステムの実装を目指しています。それはGNU Classpathに基づくクリーンルーム方式のクラスライブラリと、組み込みのインタープリタを持っているからです。コンパイラはJavaのソースファイル、クラスファイル、さらにはJARファイル全体をオブジェクトコードにコンパイルできます。
歴史的にgcjはJavaをやや独特なC++の方言であるかのように扱う「極めて伝統的な」テスティングのアプローチを取ります。これは多くの良い結果をもたらしますが、残念なことに実行時のリンクのモデルがあまりに違いすぎます。そのため大きくて複雑な、特に洗練されたクラスローディングの基盤を備えたJavaアプリケーションに対して、このアプローチは破綻してしまうのです。
GCC 4.0のリリースで私たちは、Binary Compatibility ABI(Application Binary Interface)と呼ばれるgcjのための新しいコンパイルのモードを実装しました。このコンパイルのアプローチはすべてのリンクを実行時まで延期し、プリコンパイルされたコードとクラスローディングの適切な相互作用に必要な、Javaのバイナリ互換性の仕様を完全に実現できます。
私たちはまた、クラスマッピングデータベースも追加しました。実行時に、クラスが定義されるとすぐに、「libgcj」と呼ばれるgcjのランタイムがこのデータベースからそのクラスを探します。 もしクラスが見つかると(クラスの「内容」が単なる名前ではなく、使用されたものであることに注意)、次にlibgcjはクラスのコンパイルされたバージョンを含む共有ライブラリにマップします。
これらの2つの変更によって、私たちはとても強力なものを得ることができます。私たちはアプリケーションレベルのどんな変更も必要とせずに、実行前にJavaプログラムをコンパイルできます。さらに、バイトコード検証の新しいアプローチによって、私たちはコンパイルされたコードの実行時の型安全性も保証できます。
RPMの構築
Fedora CoreでJavaプログラムを構築するのは簡単です。既存のビルド環境はそのまま機能するでしょう。Fedora Coreは「Ant」を出し、Javaプログラムをバイトコードに変換するのにEclipseからJavaコンパイラを利用します。
ソースRPMの書き方の説明はこの記事の範囲外ですが、Fedora RPM Guide(サイト・英語)に有益な一般情報があり、JPackage(サイト・英語)にいくらかのJava仕様のガイドラインがあります。
一度バイトコードにコンパイルされたプログラムは、さらにネイティブコードにコンパイルできます。gcjはまだJITを含んでいませんので、これは妥当なパフォーマンスを得るための手段となります。gcjは共有ライブラリを利用しますので、いくつかのケースでは既存のJITよりパフォーマンスが良いかもしれません。たくさんのアプリケーションのインスタンスを同時に実行する場合に、最も異なる結果を期待できます。
Fedoraはパッケージのネイティブなコンパイルをとても簡単にする2つのプログラムを提供します。これらはRPMの構築に利用されます。
1つ目のプログラムは「aot-compile-rpm」で、これはJARファイルを検索し、gcjを利用してそれぞれを共有ライブラリにコンパイルします。aot-compile-rpmは大きなJARファイルを(一度にコンパイルするには非常に大量のメモリを必要とするので)コンパイルの前に小さく分割するなど、有益なgcj仕様のトリックを少し知っていて、共有ライブラリの結果をリンクする(そして結果的に実行時のパフォーマンスを改善する)ために-Bsymbolicを利用します。
RPMを構築しない場合は、このプログラムの代わりに、単にそれぞれのプログラムのJARファイルを共有ライブラリにコンパイルします。最も簡単なアプローチをお見せします(前述のとおり、大きなJARではとても遅くなるかもしれません)。
gcj -fjni -findirect-dispatch -fPIC -shared \
-Wl,-Bsymbolic -o foo.jar.so
foo.jar
詳細:
- -fjniはJavaコードのネイティブメソッドがJNIを利用して実装されることをgcjに伝えます。
- -findirect-dispatchはバイナリ互換性ABIを利用することをgcjに伝えます。
- -fPICと-sharedは共有ライブラリを構築する場合に必須です。
- -Wl,-Bsymbolicは可能であれば、共有ライブラリへの参照をバインドすることをリンカに伝えます。
Fedora Coreに供給された2つ目の便利なプログラムは「rebuild-gcj-db」で、このプログラムはグローバルなクラスマッピングデータベースを更新するためにRPMをインストールまたはアンインストールし、RPMの%postと%postunセクションを実行させるのに利用されます。
rebuild-gcj-dbは規約によって、それぞれのパッケージが自身のクラスマッピングデータベースを/usr/lib/gcj(マルチアーキテクチャOSの64ビットパッケージなら/usr/lib64/gcjですが、この差異を抽象化するRPMマクロがある)の下のどこかにインストールすると仮定して動作します。次にこれらの個々のデータベースのすべてについてループし、それらをランタイムが利用するグローバルなデータベースにマージします。
gcjを利用してJavaプログラムをコンパイルすることが常に可能とは限らないことに注意します。gcjのクラスライブラリはまだ完全ではなく、時としてプログラムが利用するであろういくつかのAPIはまだ実装されていません。例えばSwingは現在、鋭意開発中です。また、Sunの警告(source)をよそに、いくつかのパッケージはプライベートなcom.sun.*やsun.*のAPIを利用します。そしてgcjは大抵の場合これらを実装しません。
何がこれを利用するのか
Fedora Core 4は多くのプログラムをコンパイルするのにgcjを利用します。
- 最初に、Fedora Coreは他のJavaプログラムをコンパイルして実行するために、AntとAntが依存する多くのものを含みます。それはまたEclipseのJavaコンパイラを含みます。
- Tomcatとそれが依存するもの。
- OpenOfficeのJavaコード。
- Eclipse IDEと、CDTなどのいくつかのEclipseプラグイン。
Fedora Core 5で公開されるもの
- RSSリーダ「RSSOwl」
- すばらしいBitTorrentクライアント「Azureus」
- 実行中のプロセスやスレッドをモニタリングするための実行分析技術「Frysk」
J2EEの実装であるJOnASアプリケーションサーバ(サイト・英語)もまた機能していますが、まだFedora Extrasのレビュープロセスを通過していません。
今後の作業
この1年でGNU Classpathのコミュニティは完成に向けて大きく前進し、私たちはこれが2006年も持続すると期待します。私たちは定期的に更新されるAPIを比較するページを持っています。ここ(source)で私たちのAPIのステータスを追跡することができます。
私たちはまたgcjにいくつかのコアとなる改良を行っています。コンパイラ、ランタイム、およびJava 5のクラスライブラリをアップデートしています。
最後に、私たちはlibgcjにJavaのセキュリティの基盤を実装しています。これで私たちはMozillaプラグイン(サイト・英語)とJava Web Startの実装であるnetx(サイト・英語)を出荷できるでしょう。
バイオグラフィ
Tom Tromeyは1990年にカリフォルニア工科大学(Caltech)を卒業しました。彼はRed HatでGNU Javaコンパイラとランタイムに取り組んでいます。彼はGNU Automakeの作者でもあります。原文はこちらです:http://www.infoq.com/articles/Java-Apps-on-Fedora-Core
(このArticleは2006年6月26日にリリースされました)