本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

エンタープライズOSGi入門: 第3回:OSGiによるアプリケーションのモジュール化

須江 信洋, クライアント・テクニカル・プロフェッショナル, IBM
須江 信洋の肖像
須江 信洋
日本アイ・ビー・エム ソフトウェア事業にてWebSphere関連製品のプリセールスを担当しつつ、テクノロジー・エバンジェリストとしてこれから「来そうな」技術をウォッチしています。Project ZeroがきっかけでGroovyにハマり、最近はGroovyの布教活動を進めています。『Groovy イン・アクション』(毎日コミュニケーションズ刊)もよろしく!

概要: 前回は、OSGi R4.2 Enterprise Specificationの概要をご紹介し、WAS V7 Feature Pack for OSGi Applicationsで提供されているサンプル・アプリケーションで具体的な利用イメージについて確認しました。
今回は、簡単なサンプル・アプリケーションを題材として、Enterprise OSGiの機能を利用したアプリケーションのモジュール化について解説します。OSGiの特徴を生かし、保守性の高いアプリケーションを構築するためのポイントを確認していきましょう。

このシリーズの他の記事を見る

日付:  2010年 10月 27日
レベル:  中級
アクティビティー: 2295 ビュー
お気軽にご意見・ご感想をお寄せください: 


アプリケーション概要

今回作成するのは、ブラウザ上でメッセージを入力して送信すると、サーバー上でメッセージを記録するだけの簡単なアプリケーションです。ただし、具体的なメッセージの記録方式は将来の拡張に備えて柔軟に変更可能にしておく必要があります。

簡単のため、メッセージの記録方式は以下の通りとします。

  • バージョン1.0では、送信されたメッセージを標準出力にそのままダンプします。
  • バージョン2.0では、送信されたメッセージをテキストファイルに記録します。

このような拡張に対応するため、アプリケーションをモジュール(OSGiバンドル)に分解してみましょう。OSGiにおけるベスト・プラクティスを参照すると、典型的な分解方法は以下のようになることが分かります。



ここではベスト・プラクティスに従い、API(Javaのinterface)を提供するパッケージと実装を別のバンドルに分離しています。矢印はエクスポートとインポートの組合せによるバンドル間の依存関係を示しますので、MessageLogger-APIバンドルがMessageLogger-ImplバンドルとMessageLogger-Webバンドルに共通のインターフェースを提供していることが分かります。
また、MessageLogger-WebとMessageLogger-Implの間にある黄色の三角形はOSGiサービス・レジストリー経由の参照を示しており、両者の間には直接の参照関係はありません。そのため、クライアントであるMessageLogger-Webを修正することなく、後でMessageLogger-Implを入れ替えることができます。


開発環境・実行環境の準備

アプリケーションを効率よく実装するためには、Enterprise OSGiに対応したメタデータやBlueprint定義ファイルの作成などを支援してくれるツールがあると便利です。今回は、無償で提供されている「IBM Rational Development Tools for OSGi Applications(以下、RDT for OSGiと表記)」を利用します。

RDT for OSGiは、Eclipse 3.6にEnterprise OSGi開発支援機能を追加するプラグインです。本記事ではインストール方法の詳細説明は割愛させていただきますので、こちらを参照して各自で開発環境を準備して下さい。

また、アプリケーションを実行するには、Enterprise OSGiに対応したランタイム(アプリケーション・サーバー)が必要です。本記事では、ランタイムとしてWebSphere Application Server V7にFeature Pack for OSGi Applicationsを適用した環境を利用することを想定しています。ランタイムのセットアップ方法については、本連載の第1回を参照してください。


Enterprise Bundle Application(EBA)作成

RDT for OSGiのセットアップが終わったら、新しくワークスペースを作成してください。

まず初めに、EBAプロジェクトを作成します。これは、従来のJavaEEにおけるEARプロジェクトに相当するもので、複数のアプリケーション・コンポーネント(バンドル)をまとめて管理するためのコンテナです。

「File – New – OSGi Application Project」を選択し、「Project Name」を指定(名称は任意ですがここでは仮にMessageLoggerとします)して「Finish」をクリックします。




APIバンドルの実装

共通で参照されるAPIを提供するバンドルを実装します。
「File – New- OSGi Bundle Project」を選択してください。



「Project Name」をMessageLogger-APIとします。「Application membership」の項目で先ほど作成したEBAに追加するためのチェックが入っていることを確認し、「Finish」をクリックします。

プロジェクトが作成できたら、以下の通りJava Interfaceを新規作成します。




        
        [MessageService.java]
        package dw.example.messagelogger.api;
        import java.util.Date;
        
        public interface MessageService {
        	public void recordMessage(String mes, Date ts);
        	public void startUp();
        }        
    

次に、このInterfaceを含むパッケージをエクスポートして、他のバンドルが参照できるようにします。プロジェクトの直下にある「Manifest: MessageLogger-API」をダブルクリックして、Manifestファイル・エディターを開きます。



Runtimeタブを開き、Exported Packagesセクションの「Add...」をクリックして”dw.example.messagelogger.api”パッケージを追加します。
さらに、「Properties...」をクリックするとバージョン指定のダイアログが表示されますので、”1.0.0”を入力します。



MANIFEST.MFタブを開くと、先ほど入力した内容がOSGiメタデータとして反映されていることが確認できます。


        
        Export-Package: dw.example.messagelogger.api;version="1.0.0"
    

このように、RDT for OSGiを利用することでOSGiメタデータの定義を容易に行うことができます。内容を確認したら、Ctrl-S等でファイルを保存してください。


サービス・バンドル(Ver 1.0.0)の実装

APIの実装を提供するバンドルの初期バージョンを実装します。
「File – New- OSGi Bundle Project」を選択してください。
「Project Name」をMessageLogger-Implとします。「Application membership」の項目で先ほど作成したEBAに追加するためのチェックが入っていることを確認し、「Finish」をクリックします。

プロジェクトを作成したら、まずAPIバンドルを参照するためにインポートの設定を行います。プロジェクトの直下にある「Manifest: MessageLogger-Impl」をダブルクリックして、Manifestファイル・エディターを開き、Dependenciesタブを開きます。
Imported Packagesセクションの「Add...」をクリックして ”dw.example.messagelogger.api(1.0.0)” を追加し、Ctrl-S等でファイルを保存してください。



プロジェクトが作成できたら、以下の通りJava Classを新規作成します。(MessageServiceインターフェースの追加をお忘れなく。)




        
        [MessageServiceImpl.java]
        package dw.example.messagelogger.server;
        import java.util.Date;
        import dw.example.messagelogger.api.MessageService;
        
        public class MessageServiceImpl implements MessageService {
        
            @Override
            public void recordMessage(String mes, Date ts) {
                System.out.println("[MessageService] " + mes 
              + " (TimeStamp=" + ts + ")");
            }
        
            @Override
            public void startUp() {
                System.out.println(">> MessageService Start.");
            }
        }        
    

次に、この実装クラスをOSGiサービス・レジストリーに登録するための設定を行います。Enterprise OSGiでは、サービス・レジストリーへの登録を宣言的に行うためBlueprintサービスが仕様化されており、XMLを作成してOSGI-INF/blueprintに配置すればOSGiフレームワークがサービスの管理を行ってくれます。

RDT for OSGiではBlueprint定義ファイルの作成支援機能も提供しています。MessageLogger-Impleプロジェクトを右クリックし、「New – Other」を選択してウィザードの「OSGi」を展開し、「Blueprint File」を選択すると空の定義ファイル(デフォルトではblueprint.xml)が作成されます。



XMLファイルに<bean>と<service>を追記します。


        
        <?xml version="1.0" encoding="UTF-8"?>
        <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
        	<bean id="messageservice"
        	    class="dw.example.messagelogger.server.MessageServiceImpl"
        		init-method="startUp">
        	</bean>
        
        	<service ref="messageservice"
        	    interface="dw.example.messagelogger.api.MessageService" />
        </blueprint>        
    

ここでは、<bean>で実装クラスを指定し、<service>で公開するインターフェース型を指定してサービス・レジストリーに登録しています。


Webアプリケーション・バンドルの実装

ユーザー・インターフェースとなるWebアプリケーションを提供するバンドルを実装します。

「File – New- OSGi Bundle Project」を選択してください。
「Project Name」をMessageLogger-Webとします。「Configration」をOSGi Web Configurationとし、「Application membership」の項目で先ほど作成したEBAに追加するためのチェックが入っていることを確認して「Finish」をクリックします。



プロジェクトを作成したら、先ほどと同様にAPIバンドルを参照するためのインポートの設定を行います。Manifestファイル・エディターを開き、Dependenciesタブから”dw.example.messagelogger.api(1.0.0)” を追加してください。

次に、以下の通りServletを新規作成します。




[ReceiverServlet.java] (doGetメソッドのみ修正)
        
        protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        	String mes = (String) request.getParameter("mes");
        	Date ts = new Date();
        	try {
        		InitialContext ic = new InitialContext();
        		MessageService service 
        			= (MessageService) ic.lookup("osgi:service/"
        			+ MessageService.class.getName());
        		service.recordMessage(mes, ts);
        	} catch (NamingException e) {
        		e.printStackTrace();
        	}
        
        	PrintWriter pw = response.getWriter();
        	pw.println("<html><body>");
        	pw.println("<h2>Message Recorded.</h2><hr/>");
        	pw.println("<h3>message: " + mes + "</h3>");
        	pw.println("<h3>timestamp: " + ts + "</h3>");
        	pw.println("</body></html>");
        	pw.flush();
        }
    

MessageServiceのインスタンスを取得する処理は、JNDIに対して”osgi:service/”という名前空間でlookupを行うことで、OSGiフレームワークに登録されているサービスを取得しています。これは、Enterprise OSGiが提供するJavaEEとOSGiの連携機能によるものです。

最後に、このServletにリクエストを送るJSPをindex.jspとしてWebContentの直下に作成してください。


        
        [index.jsp]
        <html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Message Logger Service</title>
        </head>
        <body>
        <form action="<%=request.getContextPath()%>/ReceiverServlet">
        メッセージ:<input name="mes" type="text" value=""></input><br/>
        <input type="submit" value="送信"></input>
        </form>
        </body>
        </html>
    


アプリケーションのデプロイ

ここまでの作業で一通りアプリケーションの実装が完了したので、アプリケーションをEBAファイルとしてエクスポートしWebSphere Application Server(WAS)にデプロイします。

最初に作成したEBAプロジェクト(MessageLogger)を右クリックし、「Export – OSGi Application(EBA)」を選択します。



エクスポート先を指定し、「Finish」をクリックします。



次に、WASを起動し、管理コンソールを開きます。
「アプリケーション - アプリケーション・タイプ – アセット」を選択し、「インポート」をクリックしてEBAファイルをアップロードします。(詳細設定はデフォルトのままでかまいません。)



「アプリケーション - アプリケーション・タイプ – ビジネス・レベル・アプリケーション」を選択し、「新規作成」をクリックして、「名前」をMessageLoggerとします。



「適用」をクリックした後、「デプロイ済みアセット」セクションで「追加 – アセットの追加」を選択します。



アップロード済みのEBAを選択して追加します。設定内容はデフォルトのままでかまいませんが、必要に応じてコンテキスト・パスなどを適宜変更してください。


アプリケーションの実行

ビジネス・レベル・アプリケーションの一覧からMessageLoggerアプリケーションを開始し、ブラウザでhttp://localhost:9080/MessageLogger-Web/ を開きます。



メッセージを入力して送信ボタンをクリックすると、以下のような送信結果画面が表示されます。(エラーが発生した場合は、SystemOut.logなどを確認の上、ソースコードの記述ミスがないか確認してみてください。)



メッセージ送信サービスのVer 1.0.0では、メッセージは標準出力にそのままダンプしているだけですので、入力した内容がWASのSystemOut.logに出力されているはずです。


        
 [SystemOut.log]
 [10/10/25 6:25:01:484 JST] 00000017 SystemOut
 O [MessageService] test test (TimeStamp=Mon Oct 25 06:25:01 JST 2010)        
    


サービス・バンドル(Ver 2.0.0)の実装

それでは、サービスの実装を変更してみましょう。
「File – New- OSGi Bundle Project」を選択して、新しいサービス・バンドルを作成します。
「Project Name」をMessageLogger-Impl-2.0.0とします。今回は単体のバンドルとして作成しますので、「Application membership」の項目でEBAに追加するためのチェックを外してから「Finish」をクリックします。



APIバンドルのインポート設定や、Javaクラスの実装、Blueprint定義ファイルの作成などはVer 1.0.0と同様に行ってください。(新規作成が面倒であればコピー&ペーストしていただいてもかまいません。)

Manifestファイルの「Overview」タブを開き、「General Information」セクションでIDおよびNameをMessageLogger-Implに、バージョンを2.0.0.qualifierに変更します。



recordMessage()の実装を修正し、受信したメッセージをユーザーホームディレクトリの”messages.log.txt”に記録するようにします。


        
        [MessageServiceImpl.java]
        public void recordMessage(String mes, Date ts) {
        	String home = System.getProperty("user.home");
        	FileWriter writer = null;
        	try {
        		writer = new FileWriter(
        			new File(home + "/messages.log.txt"), true);
        		writer.write(
        			"[MessageService] " + mes + 
        			" (TimeStamp=" + ts + ")\n");
        		writer.flush();
        	} catch (IOException e) {
        		e.printStackTrace();
        	} finally {
        		try {
        			writer.close();
        		} catch (IOException e) {
        			e.printStackTrace();
        		}
        	}
        }
    


サービス・バンドル(Ver 2.0.0)の実装

プロジェクトMessageLogger-Impl-2.0.0を右クリックし、「Export – OSGi Bundle」を選択します。エクスポート先を指定して「Finish」をクリックします。



次に、WASの管理コンソールを開きます。
「環境 – OSGi bundle repository – 内部 bundle repository」を選択し、「新規作成」をクリックしてjarファイル(OSGiバンドル)をアップロードします。



「アプリケーション - アプリケーション・タイプ – アセット」を選択し、EBAをクリックして詳細画面を表示します。
画面右側にある「追加プロパティー」セクションで、「このアプリケーションにおけるbundleバージョンの更新」を選択します。



MessageLogger-Implの「新規バージョン」ドロップダウンリストから、2.0.0を選択して「プレビュー」をクリックします。



入れ替え後のバンドルが依存関係を満たすことを確認して、「コミット」をクリックします。



バンドルの入れ替えはアプリケーション再起動後に反映されますので、ビジネス・レベル・アプリケーションを一旦停止し、再度起動した後にWebアプリケーションからメッセージを送信してみてください。<user.home>/messages.log.txt(Windows XPの場合はc:\Documents and Settings\<user>\messages.log.txt) に記録されるはずです。


第3回:まとめ

今回は、簡単なサンプル・アプリケーションを題材として、Enterprise OSGiの機能を利用したアプリケーションのモジュール化について解説してきました。OSGiの特徴を生かして保守性の高いアプリケーションを構築するためには、適切なモジュール分割と、OSGiサービスによる間接的な参照関係を活用することが重要ですが、そのエッセンスはお伝えできたのではないかと思います。

エンタープライズOSGi入門の連載は今回で終了となりますが、ご紹介しきれなかった内容がまだまだ沢山残っています。どこかでまたお会いできる機会があれば幸いです。



ダウンロード

内容ファイル名サイズダウンロード形式
サンプル・アプリケーション(完成版)MessageLogger.zip9KBHTTP

ダウンロード形式について


参考文献

学ぶために

製品や技術を入手するために

著者について

須江 信洋の肖像

須江 信洋
日本アイ・ビー・エム ソフトウェア事業にてWebSphere関連製品のプリセールスを担当しつつ、テクノロジー・エバンジェリストとしてこれから「来そうな」技術をウォッチしています。Project ZeroがきっかけでGroovyにハマり、最近はGroovyの布教活動を進めています。『Groovy イン・アクション』(毎日コミュニケーションズ刊)もよろしく!

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere
ArticleID=555995
ArticleTitle=エンタープライズOSGi入門: 第3回:OSGiによるアプリケーションのモジュール化
publish-date=10272010
author1-email=DEVWORKS@jp.ibm.com
author1-email-cc=

タグ

Help
このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。

スライダーバーを使用することで、より多く(少なく)タグを表示します。

人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。

マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。

このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。