このところ、Javaのモジュール化技術としてOSGiが話題に上ることが多くなってきました。OSGiはもともと組込機器向けのJavaや、Eclipseプラグインの開発において広く普及してきましたが、最近ではエンタープライズJavaの領域でもOSGiを活用しようという動きがあります。2010年3月に仕様が確定したOSGi R4.2では、エンタープライズJavaにおけるOSGiの標準仕様として”OSGi Service Platform Enterprise Specification”(以下、Enterprise OSGi)が規定されています。また、主要なアプリケーション・サーバーでは様々な形でOSGiの採用が進んでいます。
現在OSGiが注目されている理由は、OSGiがJavaのランタイム環境(JavaVM)におけるモジュール化機構を補完して強化することが可能なためです。また、仕様策定や実装の面でも既に長い歴史があり、比較的枯れているという点も見逃せません。実際、Java SE 7では新たなモジュール化機構を導入することが検討されていましたが、既にOSGiがデファクト・スタンダードとなっている現状を踏まえて、OSGiに歩み寄る方向で調整が行われています。
この連載では、エンタープライズJavaのエンジニアにとって馴染みの薄かったOSGiに親しんでいただくために、サンプル・コードを動かしながら、OSGiによって何が変わるのかを具体的に見ていきたいと思います。OSGiのランタイムとしては、2010年5月にリリースされた”WebSphere Application Server V7 Feature Pack for OSGi Applications and Java Persistence API 2.0”(以下、OSGi FP)を利用します。
連載は全3回を予定しています。
第1回:OSGi概要と実行環境の導入
第2回:OSGiのエンタープライズ拡張仕様を紐解く
第3回:OSGiを使いこなすためのモジュール設計
OSGiの仕様は、”OSGi Alliance”(http://ww.osgi.org/)という非営利団体によって標準化が行われており、主要なメンバーとして、日立/NEC/Mitsubishi/NTTなどの日本企業の他、IBM/Oracle/RedHat/SpringSource(VMware)など、多くの企業が参画しています。
OSGiはもともと”Open Service Gateway Initiative”の略称で、その名の通り通信機器などの組み込みソフトウェアをJavaベースで実装するためのプラットフォームとして仕様策定が進められてきました。その後、モジュール管理の仕組みとしての優位性が評価され、応用分野が車載機器やモバイル端末などに拡大していきました。2003年にはEclipseプラグインの実装基盤としてOSGiが採用されたことにより、水面下ではありますが一般のJavaプログラマーに恩恵をもたらす技術として普及が進むことになります。(Eclipse3.0からプラグイン導入時の再起動がオプションになったことを覚えていますか?実はOSGiのおかげだったのです。)
OSGiの提供する機能のうち、重要なものは以下です。
- ランタイムにおけるモジュール間の依存関係の解決
- ランタイムにおけるモジュールのバージョン管理
- モジュールのライフサイクル管理
- モジュール・レジストリーやセキュリティーなどの基盤サービス
バンドル(Bundle): OSGiにおけるモジュールの単位
OSGiでは、モジュールをバンドル(Bundle)という単位で管理します。バンドルとは、簡単に言うとJARファイルにOSGiの規定するメタデータを付加したものです。OSGiコンテナはこのメタデータを参照して依存関係の解決やライフサイクル管理を行います。
OSGiにおけるモジュール「Bundle」
バンドルは、OSGiコンテナのない通常の環境では単なるJARファイルとして扱えますので、従来のJava環境との親和性が高いのも特徴のひとつです。
OSGiが提供する重要な要素が、バンドルに閉じたクラス参照機構の提供と、Import-Package/Export-Packageによるバンドル間の依存関係の明示です。
通常のJava環境では、JARファイルでモジュールを分割していたとしても、実行時にはクラスパスで指定された全てのクラスがフラットな空間に読み込まれてしまい、モジュール単位(JAR単位)での参照制限を行うことが困難でした。結果として、モジュール間での意図しないクラスの競合などが発生するリスクがあります。典型的なのが、「xxx.jarとyyy.jarがいずれもxerces.jarに依存しているが、必要なxerces.jarのバージョンが異なる」という ケースです。特に、依存関係が複数階層に及ぶ場合、依存関係を手動で追跡することは困難を極め、実行環境で初めて問題が発覚するということが少なくありません。
問題は、通常のJava環境では実行時のモジュール管理機能が不十分だということに起因しています。そこで、OSGiでは以下のアプローチによってこの問題を解決しています。
- クラスパスの参照はバンドル毎に分離する(クラスローダーをバンドル別に作成)
- Export-Packageでバンドル外部に公開するインターフェースを明示する(Javaのパッケージ単位)
- Import-Packageでバンドルが依存するインターフェースを明示する(Javaのパッケージ単位)
- OSGiコンテナがバンドルのロード時に依存関係をチェックする
また、OSGiのバンドルにはバージョン番号が指定できるようになっており、依存関係を指定する際に「バージョン2.0.0以上」のように範囲指定を行うことも可能です。また、依存関係は「必須」「オプション」のいずれかが指定できるため、例えば「ロギング機能を提供するバンドルが利用可能であればログを出力する」といったように、環境に合わせてバンドルの挙動を柔軟にカスタマイズすることも可能です。
OSGiによる依存性解決
OSGiではバンドルのライフサイクルを定義しており、バンドルをインストールして実行するところから、停止してアンインストールするところまでの一連のステートと、ステートが変更になる際に実行されるライフサイクルメソッドが規定されています。ライフサイクルメソッドはBundleActivatorのサブクラスに実装し、バンドルのメタデータで実装クラスを指定します。
Bundleのライフサイクル
このように、バンドル単位でのライフサイクルが規定されていることで、モジュール(バンドル)を動的にロード・アンロードすることが可能になり、その際の挙動も自由に指定することができるようになっています。
従来、エンタープライズ・アプリケーションの分野では、このような動的なモジュールの交換はあまり必要とされていませんでした。というのも、一般的なWebシステムではスケールアウト構成を組むことで部分的なメンテナンス停止を許容するように設計されていることが多く、単一システムのレベルでの動的なモジュール交換は必須ではなかったからです。
しかし、動的なモジュール交換のニーズは本当に皆無なのでしょうか?裏を返せば、動的なモジュール交換が技術的に困難だったために、スケールアウト構成などで工夫して対処してきたと考えることもできます。あくまで筆者の私見ですが、OSGiの登場によって、今まで抑圧されてきた「モジュールの動的交換」のニーズが表面化する領域もあるのではないかと考えています。
本連載では、Enterprise OSGiに対応したアプリケーション・サーバーとして、WAS7.0にOSGiベースのアプリケーションを利用するためのFeature Pack(OSGi FP)を適用したものを利用します。
実は、WASは6.1から内部がOSGi化されていたのですが、ユーザーアプリケーションは従来通りEAR/WARでのデプロイを行うようになっていました。OSGi FPを適用することで、ユーザーアプリケーションもOSGiバンドルとしてデプロイすることが可能になります。
導入の手順は次のようになります。
(1) WAS7.0のインストールとFixPack9の適用
(2) IBM Installation Managerのダウンロードとインストール
(3) OSGi FPの導入
(4) サーバー・プロファイル作成
(5) サンプルアプリケーションの導入と実行
【FAQ】 WebSphere Application Serverを最新レベルにするには を参照し、WAS7.0に最新のFix Pack(FP9以上)を適用してください。
導入済みのWAS7.0の環境がない場合は、WAS7.0評価版、ないしは無償のWAS7.0開発者版をご利用ください。
IBM Installation Managerのダウンロードとインストール
OSGi FPは、IBM Installation Managerから導入することができます。(今後、IBM製品の導入はInstallation Managerに統合されていく予定です。)
次のページにダウンロード先へのリンクがあります。
最新のInstallation Manager(2010/6/14現在は1.3.4.1)のダウンロード先(HTTP)のリンクを選択します。
ダウンロードにはIBM IDによるログインが必要ですので、アカウントを作成されていない場合はこの機会にご登録ください。(無償)
ダウンロード画面では、対象のプラットフォームの”Download now”を選択します。
ダウンロードしたzipファイルを展開し、install.exe(install.sh)を実行します。
パッケージのインストール画面で、”IBM Installation Manager”にチェックを入れ、「次へ」を押してください。
次に、使用条件に同意し、インストール先のディレクトリー(任意)を指定します。
指定した内容に誤りがないことを確認し、「インストール」を押します。
インストールが完了したら、Installation Managerを再起動してください。
再起動後に、IBM IDとパスワードの確認がありますので入力してください。
OSGi FPは導入の前提条件としてWAS7.0FP9以上を必要としますが、Installation Managerの現在のバージョンではWAS7.0を認識することができませんので、最初にWAS7.0の登録情報をインポートする必要があります。
Installation Managerの初期画面で「インポート」を選択します。
WAS7.0のインストール・ディレクトリーを指定して、「次へ」を押します。
共有リソース・ディレクトリーが未登録の場合、登録を求められますので、十分な空き容量のある適当なディレクトリーを指定してください。
要約情報を確認し、問題がなければ「インポート」を押します。「インポートは完了しました」というメッセージが表示されれば、無事にインポートが行われています。
Installation Managerの初期画面に戻り「インストール」を選択します。
“IBM WebSphere Application Server V7 Feature Pack for OSGi and Java Persistence API 2.0”にチェックを入れ、「次へ」を押します。(前のステップでWAS7.0の登録情報のインポートに失敗していると、次へ進めません。)
使用条件に同意し、FPの適用対象となるWASのインストール・ディレクトリーを指定します。
インストールするフィーチャーの選択では、”OSGi Applications”を選択してください。(”Java Persistence API 2.0”は必要であれば選択してください。)
要約情報を確認し、「インストール」を押します。
インストールが完了したら、「プロファイル管理ツール」にチェックを入れた状態で「終了」を押します。
前のステップの最後でプロファイル管理ツールを起動していますので、プロファイル管理ツールの「ようこそ」画面が表示されているはずです。
「プロファイル管理ツールを起動」ボタンを押します。
OSGiに対応した新しいサーバー・プロファイルを作成するため、右上の「作成」を押します。(既存のサーバー・プロファイルをOSGi対応にする場合は「拡張」を選択してください。)
環境の選択画面では、「OSGi Applications Feature付きApplication Server」を選択します。
後は通常通りサーバー・プロファイルを作成してください。
OSGi FPを適用すると、<WAS_HOME>/feature_packs/ariesディレクトリー以下にツールやサンプルアプリケーションが導入されます。
samples/blabberの下に簡単なアプリケーションが提供されていますので、実際に導入して動かしてみましょう。詳細な導入手順はReadme.txtに記載されていますので、ここではWindows環境での導入手順の概略のみ説明します。
以下の項目は環境に合わせて適宜読み替えてください。
<WAS_HOME>: WAS導入ディレクトリー
<PROFILE_NAME>: OSGi FPを有効にしたプロファイル名
<NODE_NAME>: ノード名(管理コンソールで確認可能)
まず、WASを起動します。 (<WAS_HOME>\profiles\<PROFILE_NAME>\bin\startServer.bat server1)
次にコマンドプロンプトを起動し、<WAS_HOME>\feature_packs\aries\samples\blabber へ移動して、次のコマンドを実行すると、WASに組み込まれたDerby上にデータベースが作成されます。
> ..\..\..\..\derby\bin\embedded\ij.bat createBlabberDb.sql
データソース作成などの環境設定を行うJythonスクリプトが提供されていますので、実行します。
> ..\..\..\..\profiles\<PROFILE_NAME>\bin\wsadmin.bat -f blabberSampleInstall.py setupOnly server1 <NODE_NAME>
--------------
SETUP COMPLETE
--------------
と表示されれば、スクリプトの実行は完了です。
次に、アプリケーションが参照するOSGiバンドルを登録します。WASの管理コンソールの「環境 – OSGi bundle repository - 内部bundle repository」を選択します。
「新規作成」ボタンを押し、<WAS_HOME>\feature_packs\aries\installableApps\com.ibm.json.java_1.0.0.jar をアップロードします。「ローカル構成が変更されました」というメッセージが表示されたら、「保存」をクリックして構成を反映します。
最後にアプリケーションを登録しますが、一旦EBAファイル(Enterprise Bundle Application、通常のEARファイル相当)をアセットとしてインポートし、アセットを参照するBLA(Business Level Application)を登録するという手順を踏みます。EBAファイルに関しては次回詳しく説明します。
WASの管理コンソールの「アプリケーション – アプリケーション・タイプ – アセット」を選択します。
「インポート」ボタンを押し、<WAS_HOME>\feature_packs\aries\installableApps\com.ibm.ws.example.blabber.app.eba をアップロードします。その他の設定はデフォルトのままで、インポートを行います。「ローカル構成が変更されました」というメッセージが表示されたら、「保存」をクリックして構成を反映します。
次に、「アプリケーション – アプリケーション・タイプ – ビジネス・レベル・アプリケーション」を選択します。
「新規作成」ボタンを押し、アプリケーションの名前を指定します。(任意ですがここではblabberとしています。)
「適用」を押し、「ローカル構成が変更されました」というメッセージが表示されたら、「保存」をクリックして構成を反映します。
まだBLAの中は空なので、起動可能な状態になっていません。
新しく追加したBLAをクリックし、詳細設定画面を開きます。「デプロイ済みアセット」の「追加」のプルダウンから、「アセットの追加」を選択します。
登録済みの”com.ibm.ws.eba.example.blabber.app.eba”を追加します。
オプションの設定はデフォルトのまま追加を行います。「ローカル構成が変更されました」というメッセージが表示されたら、「保存」をクリックして構成を反映すると、BLAが起動可能な状態になります。
BLAを選択して、「開始」ボタンを押してください。
ブラウザーから http://localhost:9080/blabber を開くと、次の画面が表示されます。(ポート番号は環境に合わせて読み替えてください。)
“Click here to sign-up!”を押してユーザー登録を行ってからログインすると、次のようなTwitterライクな画面が表示されます。
今回は、OSGiの概要と、エンタープライズ分野への広がりについて説明し、OSGiアプリケーションの実行環境としてWAS V7 Feature Pack for OSGi Applicationsの導入手順をご紹介しました。
次回からは、この環境を利用して、Enterprise OSGiの仕様や使いどころについて解説していきたいと思います。
-
OSGi Alliance
-
Introduction to OSGi
-
My developerWorks Groups:OSGiファン
-
developerWorks Japan:WebSphere Application Server: WebSphere Application Server の技術情報サイト
-
WebSphere Application Server 製品情報
-
WebSphere Application Serverの評価版・開発者版ダウンロード

須江 信洋
2007 年日本アイ・ビー・エム(株)入社、ソフトウェア事業にてWebSphereソフトウェアの技術支援を担当。外資系ソフトウェアベンダーなど数社での勤務経歴あり、2000年から一貫してサーバーサイドJavaに関わってきた。最近はエンタープライズシステム開発の新しい流れに注目し、Groovyを中心としたスクリプト言語、およびエンタープライズOSGiに取り組んでいる。
ご意見・コメントはhttp://twitter.com/nobusueまでお願いします。
