GlassFish v3が埋め込み可能に

サーブレットコンテナのJettyには埋め込み用のインターフェースがあって、コンテナを単なるライブラリかのように扱って既存のJVM内でサーブレットを起動することができます。これは中々便利で、例えば「mvn jetty:run」なんていうのはMaven製のウェブアプリケーションをテストするための標準手段になっていますが、これはこの埋め込み機能を使ってMaven内でJettyを走らせるという仕組みです。常々GlassFish v3でもこれをやりたいと思っていましたが、ようやっと人様に見せられるような形になったのでアナウンスします。まだまだ不安定ではありますが、Hudsonはちゃんと走ります。


仕組みは簡単です。GFv3はHK2というお手製のモジュールシステム上で動作するのですが、HK2は別のモジュールシステム向けのラッパとして振る舞う事もできます。実際、
眠らない男Sahooはこれを使って、GFv3はOSGiアプリケーションとして動作させる事に成功しました。僕がやったのはこれの逆で、HK2をラッパとして使って単一のクラスローダー上で全てを動かすという方向です。勿論モジュールの隔離とかは全然できませんが、結果として、GFv3モジュールjarファイルをただclasspathに入れてスタートさせられるわけです。


この原理の上に、ちょっとしたAPIを被せて見栄えをよくしたら、埋め込みGlassFish v3のできあがりです。使いかたはこんな感じになります。

GlassFish glassfish = new GlassFish();
// port=8080でHTTP接続を受け付ける最小限の設定をする
glassfish.minimallyConfigure(8080);

GFApplication app = glassfish.deploy(new File("path/to/simple.war"));

...

app.undeploy();
glassfish.stop();

だから何なの?

GFv3は非常に拡張性の高いアプリケーション・サーバです(Eclipseみたいに拡張ポイントを定義する仕組みみたいのがあるのです)。GFv3と同じJVMで動作していると、この拡張ポイントをアプリケーション内で記述してGFv3に組み込んだり、あるいは既存のコンポーネントをモジュール単位ではなくコンポーネント単位で交換したり無視したりできます。これは、GFv3を単独のプロセスで起動していると難しいことです。もう一つのメリットは、GFv3の任意のエディションを埋め込めるということです。サーブレットしか使ってないならそれでもいいですし、EJBスクリプト言語サポートやJMXサポートが欲しいとなったら対応したエディションに移行すればいいだけの事です。この点でGFv3はJettyよりも優れていると思います。


これによって可能になることを想像してみてください。例えば、ウェブサービスをend-to-endでテストするなんていうのはどうでしょうか。これを全てJUnitのテストケースとして書けます。もう環境変数の設定も別途アプリケーションサーバをインストールすることも必要ありません。デバッガだって一つのプロセスにアタッチするだけでいいし簡単になる。アプリケーションサーバを運用環境で稼働させる選択肢も増えます。


さらにダメ押しのメリットはパフォーマンス。クラスローダーの隔離を失った代わりに、クラスローディングは超高速になります。僕のシステムでは、サーバの起動とウェブアプリケーションの配備は300msしかかかりません。JBossとかTomcatとか使っている皆さん。起動してデプロイするのに何秒かかってますか?こないだOC4JにHudsonをデプロイしたら15秒位かかりましたよ。

maven-glassfish-plugin

ただのAPIだと使いかたがピンとこない人がいるかもと思ったので、maven-jetty-pluginと同じ要領でmaven-glassfish-pluginを書いてみました。ウェブアプリケーションMavenで書いている時に、「mvn glassfish:run」とやればOK。ライブラリやクラスファイルをwarに組み立てることなくテストできます。


似たようなのをAnt向けにも書こうと思っていますので乞う御期待。

まとめ

こういうのをどんどんやってくれい、という方も、そんなのはどうでもいいから○△□を実装してよ、という方も、フィードバックをよろしくお願いします。JavaOneに来る方は、TS-5921 GlassFish Project v3 as an Extensible Server Platformというセッションの中でこれについても喋る予定なので、ぜひ見にきてください。初日の夕方です。