Apache Geronimoアプリケーション・サーバーは非常に巧妙なアーキテクチャーで設計されており、カーネルは、どのコンポーネントにも直接依存することがありません。カーネルは、サービスに関するフレームワークであり、サービスのライフサイクルとレジストリーを制御します。カーネルはJ2EE(Java™ 2 Platform, Enterprise Edition)に基づいてはおらず、サービスやコンポーネントと動作しながら、特定なコンフィギュレーションを構築します。その特定なコンフィギュレーションの1つが、完全なJ2EEスタックです。Geronimoのサービスの大部分は、GBeanを通して追加、コンフィギュレーションされ、アプリケーション・サーバー全体の一部となります。GBeanは、コンポーネントをカーネルに接続するためのインターフェースです。各GBeanは他のGBeanと共に状態を維持し、また他のGBeanに依存し、他のGBeanと相関関係を持ち、そしてカーネルや他のGBeanからのイベントに対して動作します。図1は、GeronimoカーネルとGBeanとの関係を図で表現したものです。
図1. GeronimoカーネルとGBeanとの関係
GBeanをカーネルにプラグインするには、プラン(plan)と呼ばれるコンフィギュレーション・ファイルでIoC(Inversion of Control)や依存性注入(dependency injection)を行います。これはつまり、GeronimoでGBeanを使うにはプランの中でXML宣言すること、またGBeanは他のGBeanへの依存関係(属性や参照によってコンフィギュレーションされます)を持っているかも知れない、ということを意味します。リスト1は、GBeanコンフィギュレーションの一例を示しています。
リスト1. GBeanコンフィギュレーションの例
<gbean name="DefaultThreadPool" class="org.apache.geronimo.pool.ThreadPool">
<attribute name="keepAliveTime">5000</attribute>
<attribute name="poolSize">30</attribute>
<attribute name="poolName">DefaultThreadPool</attribute>
</gbean>>
|
このアーキテクチャーで最も興味深い部分は、プラン・ファイルを編集し、また、GBeanのXML宣言を変更することによって、どんなコンポーネントでもGeronimoスタックに追加、削除できる、という点です。
多くのGBeanでは、JettyやTomcat、OpenEJBなど、他のオープンソース・プロジェクトやコードをGeronimoスタックの一部とすることができ、しかもこれらのコンポーネントに対してJSR-77ライフサイクル機能を提供することができます。Javaベースの強力なコンポーネントの一例が、OpenSymphonyのQuartzスケジューラーです。この記事では、Quartz GBeanを作成し、Geronimoの中にQuartsスケジューラーとして統合する方法について解説します。
ほとんどのアプリケーション・サーバーは、出荷時にはcronジョブあるいはデーモン・ジョブを実行する機能が付いておらず、これらの機能を持たせるためには大幅な修正が必要です。一部のアプリケーション・サーバーにはデーモン風のアプリケーションを作成するためのAPIがありますが、表現力豊富で完全な機能セットを提供しているものは、ほとんどありません。
OpenSymphonyの開発によるQuartzは、オープンソースでJavaベースの強力なスケジューラーです。その機能の中には、カスタム化スケジューリング、スケジュール・パーシスタンス(多くのタイプのパーシスタンス機構で使用できます)、リモート・スケジューリング機能、フォールト・トレランス、クラスタリング、等々があります。Quartzは単独で実行することもできますが、その豊富な機能を考えると、J2EEアプリケーション・サーバー・スタックに含めるための候補として最適です。QuartzをGeronimoの中に統合するためには、スケジューラー・サービスを起動停止するGBeanを作ります。
GBeanの開発は単純で、数ステップで行うことができます。GBeanを開発するためには、まだ不安定なM4(Milestone 4)ブランチからGeronimoソースコードをダウンロードする必要があり、また、Geronimoのビルド方法をよく知っている必要があります(これに関する詳しい情報を網羅したGeronimo Wikiへのリンクが参考文献にあります)。GBeanは、属性や参照、オペレーションを持つことができます。各GBeanは、少なくとも下記の指針に従っている必要があります。
- ライフサイクル・イベントを処理する場合には、org.apache.geronimo.gbean.GBeanLifecycleインターフェースを実装していること。
- コンストラクターを提供していること。
- doStart()やdoStop()、doFail() などのメソッドを実装していること。
- コンストラクターを記述したGBeanInfo静的イニシャライザーを提供していること。
- public static GBeanInfo getGBeanInfo() メソッドを実装していること。
- そのGBeanを使うためのプランを作成できること、または既存のプランを編集できること。
こうした指針を念頭に置くと、GBeanは、少なくともリスト2のようなスケルトン構造を持ったものになるはずです。
リスト2. GBeanスケルトンの例
/**
* Quartz GBean
*/
public class QuartzGBean implements GBeanLifecycle {
private static final Log log = LogFactory.getLog(QuartzGBean.class);
public QuartzGBean() {
}
public void doFail() {
log.info("Service failed");
//Insert failure code here
}
public void doStart() throws Exception {
log.info("Starting service");
//Insert startup code here
}
public void doStop() throws Exception {
log.info("Stopping service");
//Insert stopping code here
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("QuartzGBean",
QuartzGBean.class);
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
|
私は何度も『少なくとも』と強調しました。これは、すべてのGBeanは、必ずリスト2に示すような宣言や実装を含む必要があるためです。もし、デフォルト以外のコンストラクターが使用される場合、あるいは属性や参照、呼び出し可能な(callable)オペレーションが必要な場合は、GBEAN_INFO静的イニシャライザーは、それぞれsetConstructor() やaddAttribute()、addReference()、addOperation() を呼ぶ必要があります。このインスタンスには、特別なコンストラクターやオペレーション、属性、参照などはないので、これらのコールは必要ありません。
Quartzで必要なことは、Geronimoアプリケーション・サーバーのライフサイクルに合わせて起動停止することだけなので、GBeanと統合するプロジェクトとしてQuartzは最適です。つまり、Geronimoが起動するとQuartzが起動し、Geronimoが停止したらQuartzも停止するようにする、ということです。
この例では簡単にするために、Quartzコンフィギュレーションとしては、Quartzのディストリビューションに付属しているデフォルトを使います。これらのデフォルトは、.jarファイルの一部であるquartz.propertiesファイルの中にあります。パーシスタンス・レイヤー用のデータベースや、リモート・スケジューリングなど、高度なオプションを使うようにQuartzをコンフィギュレーションするためには、カスタムのquartz.propertiesファイルを作成する必要があります。(これらのオプションのコンフィギュレーションに関する詳しい情報については、参考文献に挙げた、OpenSymphonyのWebサイトへのリンクを見てください。)
Quartzスケジューラーは、単にStdSchedulerFactory.getDefaultScheduler() を呼んでスケジューラー・オブジェクトを取得するだけなので、簡単に起動、停止することができます。Quartzを起動するには、Scheduler.startup() メソッドを実行します。Quartzを停止するには、Scheduler.shutdown() メソッドを実行します。QuartzのライフサイクルをGeronimoに追従するようにするためには、GBeanのdoStart() メソッドの中にstartup() コールを置き、GBeanのdoStop() メソッドの中にshutdown() コールを置きます。リスト3は、Quartzコードを追加した後の完全なGBeanを示しています。
リスト3. 新しいQuartzGBean
package org.apache.geronimo.quartz;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
/**
* Quartz GBean
*/
public class QuartzGBean implements GBeanLifecycle {
private static final Log log = LogFactory.getLog(QuartzGBean.class);
public QuartzGBean() {
}
public void doFail() {
log.info("Service failed");
try {
doStop();
} catch (Exception e) {
log.error("doStop() failed", e);
}
}
public void doStart() throws Exception {
log.info("Starting service");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
}
public void doStop() throws Exception {
log.info("Stopping service");
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.shutdown();
} catch (SchedulerException se) {
log.error("Cannot shutdown scheduler.", se);
}
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("QuartzGBean",
QuartzGBean.class);
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
|
QuartzGBeanコードは単純に見えるかも知れませんが、やはりコンパイルして適切な .jarファイルをビルドする必要があります。Geronimoはビルド・ツールとしてApache Mavenを使っているので、この例でもQuartz用のMavenモジュールを使っています(参考文献には、MavenのWebサイトへのリンクがあります)。Mavenモジュールを作成するには、project.xmlファイルとproject.propertiesファイル、maven.xmlファイル、そしてソースコードが必要です。この記事用のダウンロード・コードには、GeronimoでQuartzGBeanをコンパイルするための完全なMavenビルド・モジュールが含まれています。このコードのコンパイルは、下記の手順で行います。
- geronimo/modulesディレクトリーにアーカイブ・ファイルをダウンロードし、そこで解凍します。quratzディレクトリーが作られ、その下に、QuartzGBean.javaコードやユニット・テストなどを含んだ、ビルド用のインフラが作られます。
- geronimo/modules/quartzディレクトリーの中にいることを確認してから、コマンドラインでmavenをタイプします。これによってGBeanがコンパイルされ、ユニット・テストされ、そしてgeronimo-quartz-1.0-snapshot.jarファイル(Mavenリポジトリーの中に保存されています)の中にGBeanがパッケージされます。
さて、.jarファイルは作成したので、このGBeanを使用するためにGeronimoビルドに少し変更を加える必要があります。GBeanを作成する際には、通常、GBeanをデプロイするためのプランを作成します。この場合では、サーバーが起動したらGBeanも起動するようにするために、既存ファイルの幾つかを編集します(手動でのコンフィギュレーションの起動、デプロイは行いません。)Geronimoが新しいQuartzGBeanを使うようにコンフィギュレーションするためには、下記のステップを行います。
- Mavenが自動的に適切なバージョンをダウンロードするように、GeronimoビルドにQuartzバージョンを追加します。geronimo/etcディレクトリーにあるproject.propertiesファイルを編集し、下記を追加します。
quartz_version=1.4.5
- Quratzと新しい .jarファイルを使うように、アセンブリー・モジュールを整えます。geronimo/modules/assemblyディレクトリーで、リスト4に太字で示すコードを、dependenciesセクションにあるproject.xmlファイルに追加します。
リスト4. アセンブリーのproject.xml依存関係<dependencies> . . . <!--Quartz --> <dependency> <groupId>opensymphony</groupId> <artifactId>quartz</artifactId> <version>${quartz_version}</version> <properties> <repository>true</repository> </properties> </dependency> <dependency> <groupId>geronimo</groupId> <artifactId>geronimo-quartz</artifactId> <version>${pom.currentVersion}</version> <properties> <repository>true</repository> </properties> </dependency> . . . </dependencies>
Geronimoビルドは<repository>true</repository>コードによって、最終のGeronimoアセンブリーに含まれる .jarリポジトリーの中に .jarファイルを追加します。これで指定の .jarファイルを持つGeronimoビルドができあがることになります。 - GBeanと依存関係をプランとして書き出します。自分で独自のプランを作成することもできますが、Geronimoが起動する時にQuartzGBeanも確実に起動するようにするためには、既存のプランを編集した方がずっと簡単です。そのためには、geronimo/modules/assembly/src/planディレクトリーにあるj2ee-server-plan.xmlファイルを編集します。最後の
</dependency>タグの後、かつ最初の<gbean>タグの前で、この依存関係をプランに追加します。これをリスト5に示します。
リスト5. j2ee-server-plan.xml依存関係を追加する<!-- Quartz --> <dependency> <uri>opensymphony/jars/quartz-${quartz_version}.jar</uri> </dependency> <dependency> <uri>geronimo/jars/geronimo-quartz-${geronimo_version}.jar</uri> </dependency>
- 同じファイルにGBeanを追加します。ファイルの最後、最後の
</configuration>タグの前に、次のラインを追加します。
あとは、アセンブリー・モジュールを再ビルドするだけです。これによって新しいコンフィギュレーションと、Geronimoサーバーの更新プラン部分が作られます。アセンブリー・モジュールを再ビルドするには、ディレクトリーをgeronimo/modules/assemblyに変更し、コマンド・プロンプトでmavenをタイプします。アセンブリー・モジュールのビルドが終了すると、geronimo/modules/assembly/targetディレクトリーにgeronimo-assembly-1.0-SNAPSHOT.jarファイルができるはずです。Geronimoを実行するには、コマンドラインからjava -jar bin/server.jar-vを実行します。通常、-vはGeronimoを実行するためには必要ありませんが、ここでは何が起きているかを見られるように、ログ出力をターミナル・ウィンドウに送るために -v を含めています。
-vを付けてGeronimoを起動する際には、ログに注意して、新しいGBeanがQuartzを起動するのを見てください(リスト6)。
リスト6. GeronimoがQuartzGBeanによってログを起動する
14:53:13,462 INFO [QuartzGBean] Starting service
14:53:13,615 INFO [SimpleThreadPool] Job execution threads will use class loader of
thread: main
14:53:13,697 INFO [RAMJobStore] RAMJobStore initialized.
14:53:13,699 INFO [StdSchedulerFactory] Quartz scheduler 'DefaultQuartzScheduler'
initialized from default resource file in
Quartz package: 'quartz.properties'
14:53:13,699 INFO [StdSchedulerFactory] Quartz scheduler version: 1.4.5
14:53:13,701 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
started. |
Geronimoを停止する際には、ログの中にある違いに注意します。
リスト7. GeronimoがQuartzGBeanによってログを停止する
14:53:41,426 INFO [QuartzGBean] Stopping service
14:53:41,450 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
shutting down.
14:53:41,452 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
paused.
14:53:41,459 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
shutdown complete.
|
大部分のオープンソース・プロジェクトの場合、GBeanを書くために必要なことは、幾つかの機能を実装し、幾つかのコンフィギュレーション・ファイルを編集するだけです。しかし、JettyやTomcat、OpenEJBなどを統合するための作業では、かなり多くのコーディング修正が必要になる場合があります。そうした統合では、複数のGBeanやコンフィギュレーション、フック(hooks)が必要です。しかしQuartzのようなアプリケーションは、単に起動、停止すればよいだけなので、容易な統合を行うための候補としては理想的です。そしてオープンソース・プロジェクトの中には、Quartzと同じくらい容易
この記事の見直しをしてくださった、Apache GeronimoチームのBruce SnyderとDain Sundstromに感謝致します。
この記事は、IBM developerWorksとVirtuas Solutionsの両方に置かれています。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Quartz GBean Maven code module | quartzgbean.zip | 10KB | HTTP |
学ぶために
-
Apache Geronimo Wikiで、Geronimoに関する最新情報と、M4リリースのダウンロードに関する詳細を見てください。
- Quartz OpenSymphonyサイトを見て、このジョブ・スケジューリング・システムに関する詳しい情報を入手してください。
- 正式なApache Geronimo Web siteで、Apache Geronimoに関する最新情報を入手してください。
- Sing Li著による記事、「Geronimo! 第1回: J2EE 1.4エンジンへの道」(developerWorks, 2005年5月)を読んで、Geronimoの案内ツアーに参加してください。また、「Geronimo! 第2回: 野生のJ2EE 1.4を使いこなす」(developerWorks, 2005年5月)で、実際を学んでください。
- developerWorksのApache Geronimoプロジェクト・ゾーンには、Geronimo開発者のためのリソースが豊富に用意されています。
-
developerWorksのOpen sourceゾーンをご覧ください。オープンソース技術を使った開発や、IBM製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
- developerWorksのOpen sourceゾーンには、Apacheに関する記事や、無料のApacheチュートリアルが用意されています。
製品や技術を入手するために
-
Apache Maven Web siteから、ダウンロードに関する情報やドキュメンテーションを入手してください。Mavenはソフトウェア・プロジェクト管理と理解のためのツールであり、Geronimoアプリケーションのデプロイを自動化することができます。
- Apache Geronimoに基づくオープソースのアプリケーション・サーバーである、Gluecode Standard Editionをダウンロードしてください。
- 皆さんの次期オープソース開発プロジェクトを、IBM trial softwareを使って構築してください。ダウンロード、あるいはDVDで入手することができます。
議論するために
-
ディスカッション・フォーラムに参加してください。
- #geronimo IRCチャネルで行われているApache Geronimo teamの議論に加わってください(IRCクライアントが必要です)。

Jeff GenenderはVirtuas SolutionsのPractice Leaderであり、Javaアーキテクチャーやオープンソース・ソリューションの実装に関する企業指導を専門にしています。彼はApache Geronimoのコミッターであり、PMCメンバーです。著書にはEnterprise Java Servlets(2001年9月、Addison Wesley Longman刊)があり、現在はJBoss Live(SourceBeat Publishing刊予定)を執筆中です。