本文へジャンプ

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


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

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

  • 閉じる [x]

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

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

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


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

  • 閉じる [x]

OSGiアプリケーションを開発、利用するためのベスト・プラクティス

Graham Charters, Senior Technical Staff Member, EMC
Author photo
Graham Charters はイギリスにある IBM の Hursley 開発研究所の Senior Technical Staff Member です。彼は現在、WebSphere Application Server 製品の業務に就いており、OSGi を WebSphere の顧客にどのように周知させるかを決めています。彼は IBM Application and Integration Middleware 部門で OSGi Alliance Expert Groups の技術リーダーです。彼は Apache Aries インキュベーター・プロジェクト管理委員会のメンバーでもあり、コミッターでもあります。
Jeremy Hughes, OSGi Applications Architect, IBM
Author photo
Jeremy Hughes はイギリスにある IBM の Hursley 開発研究所で WebSphere Application Server の OSGi アプリケーション・フィーチャーの業務を行うランタイム・アーキテクトです。彼は 2001年から WebSphere Application Server の開発チームで Web サービスや OSGi 技術、Apache オープンソース・プロジェクトに関する業務を行ってきました。彼は Apache Aries インキュベーター・プロジェクトのコミッターであり、PPMC メンバーでもあります。
Tim Mitchell, Software Engineer, IBM
Author photo
Tim Mitchell は IBM の Hursley 研究所で開発者として働いています。彼は Web Services Gateway など、IBM のいくつかの Web サービス技術に関して数年間業務を行ってきました。彼は現在、WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発を行っています。
Alasdair Nottingham, OSGi Applications Development lead, EMC
Author photo
Alasdair Nottingham は IBM による WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発リーダーです。彼はイギリスにある IBM の Hursley 開発研究所で働いています。彼は 2001年から WebSphere Application Server 開発チームでメッセージング、セキュリティー、OSGi などの技術に関する業務を行ってきました。彼は OSGi Alliance 標準化組織に積極的に参加しており、また Apache Aries インキュベーターのコミッターであり、PPMC メンバーでもあります。
(An IBM developerWorks Contributing Author)
Mark Nuttall, Software Engineer, IBM
Author photo
Mark Nuttall は IBM のソフトウェア技術者であり、1997年から IBM に勤務しています。彼は現在、最近リリースされた WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発者であり、Apache Aries プロジェクトのコミッターでもあります。彼は IBM に入社して 1999年に Pervasive Computing 部門に異動して以来、OSGi 技術に関心を持っています。
Zoe Slattery, OSGi Technology Evangelist, EMC
Photo: Zoe Slattery
Zoe Slattery はイギリスの IBM Hursley に勤務する技術エバンジェリストです。彼女の現在の関心事項はエンタープライズ OSGi であり、特に Apache Aries でのオープンソースの OSGi コンポーネントの開発に関心を持っています。彼女はこれまで IT 業界の多くの分野で働いてきました。彼女は最初 FORTRAN プログラマーとして数値演算用の並列システムを扱い、また European Centre for Medium Range Weather Forecasts のためのデータ・アーカイブを管理しました。彼女は監督者として、IBM の Java 仮想マシンや Java クラス・ライブラリーのオープンソース実装の開発チームを指揮してきました。最近では、PHP 用テスト・ケースの開発に貢献し、PHP 用コア・テスト・ケースの数を 2 倍以上に増やしました。
Tim Ward, OSGi Applications JPA lead, IBM
Author photo
Tim Ward は WebSphere Application Server の OSGi アプリケーション・フィーチャーの設計と開発のリーダーです。彼は OSGi のEEG (Enterprise Expert Group) に積極的に参加しており、そこで OSGi JPA サービス仕様を共同で作成しました。現在はいくつかの RFC を指揮しています。彼は Apache Aries のコミッターでもあり、JPA の推進者でもあり、Spring Framework に関する IBM のキー・エキスパートの 1 人でもあります。

概要: OSGi 技術は 10 年以上の間、アプリケーション開発をモジュール単位で行う上での、複雑さ、拡張性、および保守に関する課題を解決してきました。IBM® WebSphere® Application Server Feature Pack for OSGi Applications and JPA 2.0の導入により、OSGi バンドルで構成されるエンタープライズ Java™ アプリケーションを開発し、WebSphere Application Server V7 にデプロイできるようになりました。この記事では、この新機能を最大限に活用し、適切に構成された OSGi アプリケーションを開発するためのベスト・プラクティスについて説明します。この記事の内容は IBM WebSphere 開発者向け技術ジャーナルから引用したものです。

日付:  2010年 7月 14日
レベル:  中級 この記事の原文:  英語
アクティビティー: 4199 ビュー
お気軽にご意見・ご感想をお寄せください: 


はじめに

OSGi のモジュール性は、Java アプリケーションの共通の課題に対処する標準的なメカニズムを提供します。OSGi 基盤の利点を、エンタープライズ Java プログラミング・モデルの形式で、エンタープライズ・アプリケーション開発者に提供するため、2007年にOSGi Allianceの EEG (Enterprise Expert Group) が結成されました。OSGi アプリケーションに対するサポートは、IBM WebSphere Application Server によるエンタープライズ・レベルのサービス品質と連携することにより、モジュール型 Web アプリケーション向けの完全で最も堅牢なエンタープライズ・サーバーを提供します。WebSphere Application Server Feature Pack for OSGi Applications and JPA 2.0 を使用すると、バージョン管理された一連の OSGi バンドルとして Web アプリケーションをデプロイし、管理することができます。またプロビジョニング基盤の一部として 1 つ以上のバンドル・リポジトリーを構成し、複数のアプリケーションが使用する共通のバンドルをホストしたり、そうした共通のバンドルを使用するアプリケーションのデプロイメントを単純化したりすることもできます。WebSphere Application Server V7 Feature Pack for SCA V1.0.1.5 更新では、サービス指向アーキテクチャー (SOA) の概念に基づき、異種混成の資産による OSGi アプリケーションの構成がサポートされるようになりました (「参考文献」を参照)。

どのような新技術であれ、「すべきこと」と「すべきでないこと」があり、それらはアーキテクトや開発者、デプロイメント技術者のためのベスト・プラクティスとしても知られています。OSGi 技術は 10 年以上も利用されてきており、その間に多くのベスト・プラクティスが生まれています。この記事では、WebSphere Application Server の OSGi アプリケーション・フィーチャーを利用して OSGi アプリケーションを作成するための、またサービス・コンポーネント・アーキテクチャー (SCA) と統合するための、重要なベスト・プラクティスについて説明します。これらのベスト・プラクティスのいくつかは OSGi の一般的なベスト・プラクティスであり、それ以外は WebSphere Application Server で提供される OSGi サポートに特有のベスト・プラクティスです。区別するために、後者に関してはその旨を明示します。


ベスト・プラクティス

この記事で説明するベスト・プラクティスは以下のとおりです。

  1. Blueprint を使用する
  2. Blueprint を使ってサービス・ベースのプロビジョニングを有効にする
  3. Blueprint を使って SCA 統合を実現する
  4. バージョン管理可能なバージョンを付ける
  5. API を実装から分離する
  6. 実装ではなく、サービスを共有する
  7. 適切なバンドルは適切なクラスと似ており、結合度が低く、凝集度が高い
  8. 分割されたパッケージや Require-Bundle を避ける
  9. 含まれているコンテンツを Application-Content ヘッダーの中に記載する
  10. WAR ではなく WAB を作成する
  11. 必須の場合にのみ Use-Bundle を使う
  12. パーシスタンス・バンドルを使用してパーシスタンス・ユニットを共有する
  13. 提供されているコンポーネント・モデルを最大限に利用する
  14. 複雑な作業はコンテナーに任せる

各ベスト・プラクティスを、以下のセクションで詳細に説明します。

1. Blueprint を使用する

Blueprint の使用は、優れたプラクティスです。Blueprint が提供するメリットとしては、POJO の開発やテストのモデルが単純化されること、コンポーネントの構成が単純になること、オープンな標準をベースにできること、などを挙げることができます。WebSphere Application Server で OSGi アプリケーションを作成する場合には特に、Blueprint の使用が推奨されます。Blueprint を使用することで、コンテナーの統合、サービス・コンポーネント・アーキテクチャー (SCA) 統合、およびサービス・ベースのプロビジョニングに対するサポートが強化されるからです。

その理由

Blueprint は、Spring フレームワークに基づく単純なコンポーネント・アセンブリー・モデルです。Blueprint は、SpringSource からの貢献を受け、OSGi Alliance によって Enterprise OSGi R4 V4.2 仕様の中で標準化されました。Blueprint は、Spring で標準化された形式であるため、Spring と同じ依存性注入パターンをサポートしています。そのため、フレームワークの API を使用しない (したがって単体テストがしやすい) 単純な Java コンポーネントを作成することができます。

developerWorks の記事、「WebSphere Application Server でエンタープライズ OSGi アプリケーションを開発する」では、WebSphere Application Server で Blueprint コンポーネント・モデルがサポートされている理由をいくつか概説しています。これらの理由は、クライアントの要件によるものであり、WebSphere Application Server での OSGi アプリケーションのサポートの大部分は、サービス・ベースのプロビジョニングや SCA 統合などいくつかの機能を有効にするため、Blueprint に依存しています。一般に、Blueprint の使用は良いアイデアですが、WebSphere Application Server で OSGi アプリケーションを開発する場合には、Blueprint を使用する意味がさらに高まります。

2. Blueprint を使ってサービス・ベースのプロビジョニングを有効にする

(WebSphere Application Server に特有のベスト・プラクティス)

Blueprint を使って OSGi サービスを開発したり使用したりする場合、Blueprint による定義を使用することで、WebSphere Application Server にアプリケーションをプロビジョニングする際のサービスの依存関係を確実に満足させることができます。

その理由

OSGi バンドルのマニフェストには、そのバンドルが別のバンドルからインポートするパッケージと、そのバンドルがエクスポートして他のバンドルで使用されるパッケージとが記述されています。したがって、特定のバンドルを指定すると、すべてのパッケージのインポートに必要な一連のバンドルを (過渡的な依存関係を含めて) 決定することが可能です。ベスト・プラクティスは、インターフェースと実装を別のバンドルに分離することです (「API を実装から分離する」を参照)。もう 1 つのベスト・プラクティスは、実装の依存関係には OSGi サービスを使用することです (「実装ではなくサービスを共有する」を参照)。これら 2 つのベスト・プラクティスの結果、パッケージの依存関係をプロビジョニングしてもインターフェースの要件を満たすだけであり、実装バンドルは提供されないことになります。WebSphere Application Server の OSGi アプリケーション・フィーチャーは、その解決法として、Blueprint による定義を使って、バンドルが提供、要求するサービスを決定させます。そして、その情報をアプリケーションがデプロイメントされる際に使用し、アプリケーションのアーカイブ (.eba) または内部バンドル・リポジトリー (WebSphere Application Server 管理によって構成、管理されるバンドル・リポジトリー) から実装バンドルをプロビジョニングします。


図 1. サービス・ベースのプロビジョニングの例

図 1 は、API バンドルと、サービスを提供する実装バンドル、そして実装バンドルのサービスを使用するクライアント・バンドルを示しています。クライアント・バンドルと実装バンドルは共に、サービスのための Java インターフェースを含む API バンドルに対し、パッケージの依存関係を持っています。クライアント・バンドルは、OSGi アプリケーションの一部であり (そのアプリケーションのコンテンツとして記載されています)、また API バンドルと実装バンドルは共有され、内部のバンドル・リポジトリーからプロビジョニングされます。API バンドルはパッケージの依存関係の結果として、WebSphere Application Server の中にプロビジョニングされます。またクライアント・バンドルと実装バンドルの両方が Blueprint を使って実装されている限り、実装バンドルもプロビジョニングされます。しかし、クライアント・バンドルと実装バンドルのいずれか一方が Blueprint を使用していない場合には、実装はプロビジョニングされません。

例えば、もし実装バンドルが Blueprint を使用し、クライアント・バンドルが Blueprint を使用していない場合には、アプリケーションは、実装バンドルなしでプロビジョニングされます。プロビジョニングする側が、サービスの依存関係がクライアント・バンドルから欠落していることを認識できないためです。もしクライアント・バンドルが Blueprint を使用し、実装バンドルが Blueprint を使用していない場合には、アプリケーションはデプロイされません。これはプロビジョニングする側がクライアント・バンドルのサービスの依存関係を満足させることができないためです。

3. Blueprint を使って SCA 統合を実現する

(WebSphere Application Server に特有のベスト・プラクティス)

他の技術との統合が予定されている OSGi アプリケーションを開発する場合には、OSGi アプリケーションのサービスの実装を Blueprint を使って定義することがベスト・プラクティスです (実際には、Blueprint を使って定義することが不可欠です)。

その理由

WebSphere Application Server では、SCA を使って OSGi アプリケーションを他のタイプ (Java EE など) のアプリケーションと統合します。また、さまざまなトランスポートやプロトコル (JMS、Web サービス、Atom など) を介して OSGi アプリケーションのサービスを公開する場合や、そうしたトランスポートやプロトコルを介してサービスの依存関係を呼び出し可能とする場合にも、SCA が使われます。そのため SCA が必要とするのは、OSGi アプリケーションが提供するサービスの記述と、その OSGi アプリケーションに必要なサービスの記述です。SCA は、必要な情報を得るために Blueprint の XML に記述された情報を再利用します。つまり、OSGi アプリケーションのサービスを SCA に公開する場合には Blueprint を使用する必要があります。OSGi アプリケーションに Blueprint を使って定義されていないサービスが含まれている場合には、Blueprint のファサードを作成しなければなりません。このファサードは、それらのサービスを Blueprint に記述し、Blueprint を使って定義されていないサービスの実装にリクエストを転送します。


図 2. Blueprint が SCA 統合をサポートする

図 2 は、1 つのバンドルを持つ OSGi アプリケーションを示しています。このバンドルは、SCA によってアプリケーションの外から呼び出されるサービスを提供します。この呼び出しは、別の SCA コンポーネント (別の OSGi アプリケーション、または Java EE アプリケーションなど) から行われる場合、または、Web サービスや JMS の呼び出しなど、特定のバインディングから行われる場合もあります。また、この同じバンドルは、SCA によってアプリケーションの外で提供されるであろうサービスも必要とします。その上、このバンドルは、別の SCA コンポーネントを呼び出す場合もあれば、特定のバインディングを呼び出す場合もあります。図 2 の最初の図では、バンドル A はBlueprint を使って実装されています。SCA は、Blueprint によるサービス定義を使うことで、ターゲットとなる OSGi サービスの識別方法や呼び出し方法を認識します。SCA は、Blueprint によるサービス参照の定義を使用しません。なぜなら、SCA はアプリケーションのマニフェスト (OSGi アプリケーションを定義するために使われる成果物) の中に十分な情報を持っており、どのサービスが有効なターゲットなのかを決定できるからです。2 番目の図では、サービスと参照が、宣言型サービス (DS) など、他のコンポーネント・モデルを使用するバンドル B で実装されています。SCA は、DS を認識しないため、これでは動作しません。3 番目の図では、Blueprint ファサード・バンドルであるバンドル C を使用して SCA にサービスを記述し、そしてバンドル B の DS サービスの実装に呼び出しを転送しています。

4. バージョン管理可能なバージョンを付ける

バンドルやパッケージにセマンティックなバージョンを付けることで、API クライアントと API プロバイダーの間を疎結合にすることができます。

その理由

OSGi では、パッケージやバンドルにバージョンを付けることができます。何もバージョンが指定されない場合、デフォルトのバージョンはゼロになります。パッケージとバンドルには、バージョンをセマンティックに付けなければなりません。そうすることで、クライアントの動作に問題を起こすような API の変更からクライアントを保護することができます。

セマンティックなバージョン管理では、バージョンによってクライアントに互換性情報を伝えられるように、バージョン管理のスキームを定義します。セマンティックなバージョン管理では、major.minor.micro という番号付けスキームを使用します。major、minor、micro は自然数 (0、1、2、など) です。

  • major バージョンの変更は、その API のクライアントに対してバイナリー互換性のない API の変更を意味します。つまり、あるバージョン 2 の API に対してコンパイルされたクライアントをバージョン 3 の API で動作させるためには、そのクライアントを再コンパイルする必要があります。バイナリー互換性のない変更の例には、インターフェースやメソッドを削除した場合などがあります。
  • minor バージョンの変更は、API は拡張されたものの、既存のクライアントを再コンパイルする必要がないことを意味します。このタイプの変更の例としては、インターフェースやメソッドの追加などがあります。
  • micro バージョンの変更は、API が変更されない変更を意味します。このタイプの変更の例としては、NullPointerException を回避するためのバグ修正などがあります。

このようにバージョン付けされた API によって、クライアントは対応可能な API のバージョンを限定することができます。パッケージをインポートする場合やバンドルを要求する場合、クライアントは対応可能なバージョンを指定することができます。例えば (1,2) の場合、クライアントはバージョン 1 のすべてのパッケージやバンドルに対応できますが、バージョン 2 のパッケージやバンドルには対応できません。この仕組みは、今後の変更ではバイナリー互換性に関する変更は major バージョンを使用して示される、ということをクライアントが認識しているからこそ機能します。

バンドルやパッケージに対してセマンティックなバージョン管理を行うと、ランタイム中に 1 つの API の 2 つのバージョンを同時に持つことができ、異なるバンドルが両方のバージョンを同時に使用することができます。

ここまで、このベスト・プラクティスでは API クライアントの観点で互換性を説明しました。「API を実装から分離する 」ベスト・プラクティスに従うと、API の実装はその API とは別のバンドルとなり、その API 実装にもセマンティックなバージョン管理のメリットが生かされます。実装する側にとって、major バージョンまたは minor バージョンの変更はバイナリー互換性がない変更を意味し、例えば、新しいインターフェースやメソッドを実装する必要があるかもしれません。(セマンティックなバージョン管理を使用する場合の他のメリットや考慮事項については、OSGi Alliance Semantic Versioning Technical Whitepaper を参照してください。)

図 3 は、ある 1 つの API の 2 つのプロバイダーを示しており、API のバージョンは同じです。OSGi では、この 2 つのプロバイダーは等価と見なされます。クライアント (右側) と実装側 (左側) は共に、どちらの API プロバイダーにもマッチする依存関係を表しています。


図 3. 2 つのパッケージのバージョンが等価である場合、クライアントと実装は任意の一方を使用することができる

図 4 は、バージョンが異なる 2 つの API プロバイダーを示しています。この図は、minor バージョンの変更による影響がクライアントと実装とで異なることを示しています。この場合、バージョン 1.0 とバージョン 1.1 の API が提供されています。クライアント A は、どちらの API プロバイダーも使用することができます。新しい API メソッドを使用するクライアント B は、バージョン番号が高い、バージョン 1.1 の API しか使用することができません。実装 A はバンドル API A で提供される API のみを使用することができ、実装 B はバンドル API B で提供される API のみを使用することができます。

サービス・レジストリーにより、リクエスト側から見えるサービスは、バンドルがバインドされているバージョンの API を実装したサービスのみに制限されている、ということを理解することが重要です。


図 4. API の minor バージョンの変更による影響はクライアントと実装とで異なる

図 5 は、クライアントの観点からも実装側の観点からも互換性のない API の変更を示しています。この場合、実装 A とクライアント A は API A にバインドされており、実装 B とクライアント B は API B にバインドされています。


図 5. API の major バージョンの変更がクライアントと実装に与える影響は同じ

5. API を実装から分離する

OSGi バンドルを開発する場合のベスト・プラクティスは、API クラスはすべて、実装クラスとは別のバンドルの中に入れることです。

その理由

API クラスを実装クラスから分離すると、大幅に柔軟性が高まります。API バンドルを別に持つことで、クライアントは任意の実装プロバイダーを使用することができます。それに加えて、複数のプロバイダーを同時に使用することができます。API クラスを実装クラスから分離しない場合、新しいプロバイダー・バンドルに接続するためにはクライアント・バンドルを再起動しなければなりません。

またこのベスト・プラクティスにより、API バンドルのパッケージ依存関係を減らすこともできます。その結果、さまざまな API の実装の間で依存関係が循環する可能性が低くなります。2 つの API 実装が内部で互いに相手の API を使用する場合、依存関係の循環が発生しやすくなります。

API クラスを別のバンドルに入れたら、どの実装パッケージもエクスポートされないようにし、公開 API を使ってその API の実装を OSGi サービスとして公開することが重要です。

図 6 のシナリオに示すクライアント・バンドルは、API クラスと実装クラスとを、1つのプロバイダー・バンドルからインポートしています。ただし、このプロバイダー・バンドルは、両方のパッケージを分離していません。また、このプロバイダー・バンドルも、実装パッケージと API パッケージの両方をエクスポートしています。これは不適切なプラクティスです。なぜならば、API クラスと実装クラスとが分離されていない上、実装クラスがエクスポートされており、サービスとして公開されていないからです。


図 6. API クラスと実装クラスが同じバンドルの中にあり、不適切に設計されたプロバイダー・バンドル

図 7 の次のシナリオに示すクライアント・バンドルは、1 つのバンドルから API パッケージをインポートし、別のバンドルから実装パッケージをインポートしています。API パッケージと実装パッケージは分離されていますが、プロバイダーは相変わらず実装パッケージをエクスポートしており、実装クラスをサービスとして公開しているわけではありません。


図 7. API クラスと実装クラスは分離されているものの、不適切に設計されたプロバイダー・バンドル

図 8 の最後のシナリオは、ベスト・プラクティスを示しています。プロバイダー・バンドルは実装パッケージと API パッケージの両方を分離しています。さらに、実装クラスは OSGi サービスとして公開されています。


図 8. API クラスと実装クラスが分離され、適切に設計されたプロバイダー・バンドル

6. 実装ではなく、サービスを共有する

OSGi バンドルを開発する場合のベスト・プラクティスは、OSGi サービス・レジストリーを使用してファクトリー・パターンを実現し、また他のバンドルによってエクスポートされるクラスのインスタンスを構築することです。「API を実装から分離する」ベスト・プラクティスと同様に、このベスト・プラクティスによって、クライアントと API、そして API 実装を疎結合にすることができます。

その理由

API と実装を分離するプラクティスによって、多数の実装を使用するクライアントから、そうした実装を抽象化することができます。そのため、あるベンダーが実装した API を、その API を利用するクライアントを変更せずに別のベンダーによる実装で置き換えることが可能となります。

API と実装の分離を効果的なものにするためには、使用する実装を事前に知らなくてもクライアントが実装のインスタンスを取得できるようなメカニズムが必要です。OSGi 以外のシステムでは通常、API のクラスの静的なファクトリー・メソッドを使って実装のインスタンスを取得します。静的なファクトリー・メソッドにより、クラスパス上にある複数の実装の中から、どの実装をインスタンス化するのかを選択します。クラス空間がフラットであるため、すべての実装を見ることができます。どの実装をインスタンス化するかの判断に使用されるアルゴリズムは、その API にだけ使えるものです。

このメカニズムは OSGi には使えません。なぜならば、API のクラスを含むバンドルは、その API の実装を含むいかなるバンドルであっても、見ることができてはいけないからです。

OSGi はもっとスマートなソリューションを、OSGi サービス・レジストリーという形で提供します。API の実装を含むバンドルは、下記のいずれか一方を行います。

  • API インターフェースのインスタンスを OSGi サービス・レジストリーに登録します。こうすることで、使用されるすべてのクライアント・バンドルに対し、実装のインスタンスは 1 つしかないことになります。
  • OSGi ServiceFactory インターフェースの実装を OSGi サービス・レジストリーに登録します。この ServiceFactory インターフェースは OSGi でサービス・インスタンスが要求された場合に使われます。この場合、ServiceFactory は、要求側の各クライアント・バンドルに返すインスタンスを選択することができます。例えば、ServiceFactory は、要求側のクライアント・バンドルすべてに対して同じインスタンスを返したり、要求側の各クライアント・バンドルに対して異なるインスタンスを返したり、またはその中間の任意の返し方をしたりすることができます。

静的ファクトリー・メソッドによるパターンの場合と同様、クライアントは実装から完全に分離されており、しかも以下の特徴があります。

  • API はすべての実装から完全に分離されます。これは OSGi のサービス・レイヤーが、それらの実装と連携してインスタンスの作成を行っているからです。
  • どの実装を返すかを決定するために使用されるアルゴリズムは、すべての API で共通しており、API ごとに異なることはありません。これは OSGi 以外のシステムで使われている静的ファクトリー・メソッドによるパターンの場合と同じです。

OSGi のサービス・レジストリーは、実行時に利用可能となったり利用できなくなったりすることがあるサービスを共有するための動的なメカニズムです。Blueprint を使用することで、API クライアントはこの動的メカニズムに対応することができます。つまり必要なサービスが利用可能になると、そのサービスをクライアント・バンドルの Bean に注入します。そのサービスが利用できなくなると、Blueprint は (代わりの実装が登録されている場合には) 代わりの実装を注入します。

7. 適切なバンドルは適切なクラスと似ており、結合度が低く、凝集度が高い

バンドルを作成する場合には、そのバンドルの機能を特定のタスクに限定します。バンドルが実行するタスクの数を少なく抑え、依存関係を可能な限り減らすよう努めます。

その理由

OSGi アプリケーションを作成する場合、新しいバンドルを作成するのではなく、既存のバンドルに多くの機能を追加したくなります。しかしそうすると、バンドルはすぐに、凝集度の低い、大きなものになり、通常は、多数のパッケージをインポートしたり、エクスポートしたりするものになってしまいます。また、多数のパッケージのインポートを隠すために Require-Bundle ヘッダーを使うのは不適切なプラクティスです。Require-Bundle ヘッダーは単に、バンドル間に密結合を追加するだけです。バンドルの依存性グラフが伸びるにつれて、ダウンロードやインストールが必須となるバンドルの数は (多くの場合は指数関数的に) 増加します。これは「hairball effect」と呼ばれることがあります (訳注: hairball は猫が毛をなめることで胃の中にできる塊)。目的が不明確なバンドルでは、単に 1 つか 2 つの単純な関数にアクセスするだけのために、何十メガバイト、さらには何百メガバイトものファイルをダウンロードして、アプリケーション内にインストールする必要がある場合があります。一方、焦点の絞られたバンドルは、ほとんど依存関係を持たず (小さな依存関係ツリー)、そのバンドルは、他のアプリケーションで容易に再利用できるでしょう。このベスト・プラクティスは、オブジェクト指向のクラス設計のベスト・プラクティスに酷似しており、その理由も同じであることに注意してください。OSGi のバンドルは、(適切に作成されたクラスの場合と同じように) 適切にカプセル化され、凝集度が高く、結合度が低くなければなりません。そうすることで、特定バージョンの他のバンドルやパッケージとの結合を防止し、再利用の可能性を高めます。

目的の不明確なバンドルの例として、ログの実装があります。この実装により、ユーザーはファイルシステム、JPA 経由でデータベース、またはメッセージ・キューへログを書き出すことができます (図 9)。ファイルシステムのロガーを使用するためには、アプリケーションはメッセージング API や JPA API 等をロードする必要があります。したがって、アプリケーションには、そのアプリケーションが使用していないロガー用の実装クラスが含まれることになります。もっと適切なソリューションは、ロギング・インターフェースと各実装を互いに分離することです (図 10)。こうすることで、アプリケーションは、そのアプリケーションで使用する 1 つのロギング・バンドルを選択して含めることができ、ロギング・バンドルの中にある余分な実装クラスや、今後使われる実装を含める必要がなくなります。


図 9. 1 つのバンドルが同じ API の複数の実装を提供している目的が不明確なシステム


図 10. 1 つの API の各実装が別のバンドルによって提供されている目的が明確なシステム

8. 分割されたパッケージや Require-Bundle を避ける

OSGi のバンドルを作成する際のベスト・プラクティスは、どのようなパッケージの場合でも、1 つのパッケージのクラスをすべて 1 つのバンドルに保持することです。1 つのパッケージを複数のバンドルに分割すると Require-Bundle を使うことになり、それらのバンドルを使用するシステムの拡張や保守がしにくくなります。

その理由

モジュール型のシステムは、結合度が低く、凝集度の高いモジュールで構成されています。各モジュールは凝集度の高い論理機能を実行し、それらの機能の間の境界は適切に定義されています。こうした目的で設計することにより、保守や拡張が容易なシステムを作成することができます。OSGi のバンドルは、パッケージ以上のレベルでモジュール化されています。

OSGi では、モジュール (OSGi の用語ではバンドル) を疎結合にすることができます。そのためには、各バンドルは、そのバンドルに必要な Java パッケージの形で自分の依存関係を宣言します。こうした依存関係は、バンドルが提供するパッケージによって実行時に満足されます。バンドルは、依存関係を提供するバンドルに直接依存するわけではありません。どのバンドルが依存関係を提供するかの判断は OSGi ランタイムに任されており、どのバンドルがフレームワークにデプロイされるのかに応じて判断されます。この効果として、特定のパッケージを提供するバンドルは、同じパッケージを提供する別のバンドルで置き換えることが可能となり、そのパッケージに依存する複数のバンドルを変更する必要がありません。

パッケージの分割が発生するのは、同じバージョンの 2 つのバンドルによって 1 つのパッケージがエクスポートされ、各バンドルによって提供される一連のクラスが異なる場合です。クラスが重複することもあります。あるいはもっと典型的な場合としては、パッケージの一部が一方のバンドルの中にあり、それ以外の部分がもう一方のバンドルの中にある場合もあります。


図 11. 分割パッケージを利用する側は Require-Bundle ヘッダーを使う必要がある


図 12. 1 つのバンドルからエクスポートされた完全なパッケージでは、バンドルの凝集度が高い

OSGi は実行時、Import-Package ヘッダーによって指定されるバンドルの依存関係を満足させるために、別のバンドルからエクスポートします。そのパッケージをエクスポートするバンドルが複数ある場合でも、そのうちの 1 つのバンドルのみを使って依存関係を満足させます。バンドルは互いに「接続」されます。同じパッケージをエクスポートする別の (インポート側のバンドルに接続されていない方の) バンドルの中でのみ存在する必要があるクラスは、インポート側のバンドルのクラスローダーからは見えません。もし、そうしたクラスをインポート側のバンドルが実行時に使おうとすると、ClassNotFoundException がスローされます。OSGi でのパッケージのインポート/エクスポート・メカニズムはパッケージ単位で 1 つのバンドルを別のバンドルへと接続する手段にすぎないため、パッケージが分割された状況に応じて 1 つのバンドルを複数の別バンドルに接続するためには、別のメカニズムが必要です。これを実現するためには、Require-Bundle ヘッダーを使用し、必要なパッケージをエクスポートするバンドルのバンドル・シンボリック・ネームを指定します。

ただしそうすると、以下のようにバンドル間が密結合されてしまいます。

  • クライアントは、そのパッケージを提供する 2 つ (またはそれ以上) のバンドルに依存することになります。
  • 提供側のバンドルがエクスポートするパッケージは、すべてクライアントから見えるようになり、またクライアント・バンドルが時間と共に改良されると、クライアント・バンドルがそうした他のパッケージに依存し始めるかもしれません。
  • そのパッケージを必要とするすべてのクライアント・バンドルを変更しない限り、そのパッケージを提供するバンドルを (シンボリック・ネームが異なる) 別のバンドルで置き換えることはできなくなります。

パッケージを複数のバンドルに分割し、その結果 Require-Bundle ヘッダーの使用が余儀なくされると、アプリケーションは密結合され、したがって、保守や拡張のコストがかさむようになります。2 つのバンドルに分割した方が理にかなうパッケージがあるとすれば、それは、その 2 つの部分の間に高い凝集性がない場合です。したがって、2 つの異なるパッケージを使用すべきです。

9. 含まれているコンテンツを Application-Content ヘッダーの中に記載する

(WebSphere Application Server に特有のベスト・プラクティス)

EBA (Enterprise Bundle Archive) ファイルの中に含まれているバンドルを、その EBA の META-INF/APPLICATION.MF の Application-Content ヘッダーの中に記載します。依存関係のバンドルを保存するための最適な場所は、バンドル・リポジトリーです。バンドル・リポジトリーに保存すると、プロビジョニングされたすべてのアプリケーションで依存関係のバンドルを利用することができます。

その理由

EBA の中に含まれているバンドルはアプリケーションのプロビジョニング方法に影響しますが、他のアプリケーションからは、アプリケーションがプロビジョニングされている限り EBA 内のバンドルは見えません。EBA の中に、Application-Content に記載されていない依存関係のバンドルが 1 つ以上含まれていると、プロビジョニング・プロセスの結果、その依存関係のバンドルが 1 台以上のサーバーの共有バンドル空間にロードされてしまうかもしれません。これは問題の原因になる可能性があります。なぜならば、他のアプリケーションが、(依存関係のバンドルに対してプロビジョニングされるはずがないにもかかわらず) その依存関係のバンドルに接続されてしまう可能性があるからです。その結果、実行時の動作が予想に反して変化する可能性があり、こうした変化の検出は非常に困難になることがあります。

含まれているコンテンツを Application-Content ヘッダーに記載すべきであるという事実とは別に、そもそもコンテンツを含められる機能は、主に開発中の便宜のために用意されており、本番環境でこの機能を使うことは推奨されない、ということを理解する必要があります。アプリケーションのコンテンツを構成するバンドルは、EBA、つまりバンドル・リポジトリーの中に含めることができます。本番環境では、アプリケーションはすべてのバンドルをバンドル・リポジトリーから取得することが推奨 (多くの場合は強制) されています。こうすることで、本番のバンドル・リポジトリーが、アプリケーション・コードの唯一のソースであるという統制を効かすことができます。

APPLICATION.MF のない EBA が提供されると、APPLICATION.MF が自動的に生成されます。Application-Content は、EBA のルート・ディレクトリーに含まれるバンドルごとに解釈されます。各バンドルのバージョン範囲は、そのバンドルの正確なバージョンにロックされます。この場合、いかなるバンドルも、他のアプリケーションと共有されたり、デプロイメント後にアップグレードされたりすることはありません。より直接的な統合を実現する IBM Rational® Application Developer 統合開発環境を利用できない場合には、APPLICATION.MF を使わずにアプリケーションをパッケージ化し、更新されたコンテンツを含む新しいアプリケーション・アセットをインポートした方が、新しいバンドルをそれぞれ内部のバンドル・リポジトリーにインストールするよりも便利かもしれません。もちろん、開発サイクルの終了までに APPLICATION.MF を作成しておかなければなりません。一般に、含まれるコンテンツは、開発環境からテスト環境へ、そして本番環境へと移るにつれ、共通性がなくなっていきます。テスト環境では、すべての依存関係を含む EBA を生成した方が便利かもしれません。そうすると、ターゲット・サーバーのバンドル・リポジトリーの状態に関わらず EBA をインストールすることができます。これは上記の理由から、本番環境では適切ではありません。

最後に、WAB ではない WAR のみを含められることに注意してください。WAR はバンドルではなく、バンドル・リポジトリーに保存することはできません。この点については、次のベスト・プラクティスを見てください。

10. WAR ではなく WAB を作成する

エンタープライズ OSGi アプリケーションを開発する際には、WAB (Web Application Bundle) を作成し、WAR から WAB への変換に依存してはなりません。

その理由

WebSphere Application Server の OSGi アプリケーション・フィーチャーは、WAR ファイルを OSGi バンドルに自動変換します (このバンドルは Web Application Bundle と呼ばれます)。このフィーチャーは OSGi を初めて扱う場合には便利ですが、自動変換によって一部の機能が使用できなくなります。そのため、開発中に WAR ファイルをバンドルに変換し、本番システムにデプロイできるようにしなければなりません。

OSGi バンドルを使用する場合、アプリケーションは、そのアプリケーションでサポート可能なバンドルのバージョン範囲を示すことができます。こうすると、アプリケーション全体を再デプロイしないで、個々のバンドルを更新することができます。この機能はモジュールが既知の識別子を持っていることに依存していますが、デプロイ時に識別子が生成される自動変換では、この機能を利用することができません。

WAR を WAB に変換する際、パッケージに対して生成されるインポートはバージョン管理されません。そのためパッケージは、必要なパッケージとバイナリーの互換性がないバージョンを選択する可能性があります。例えば、あるパッケージのバージョン 2 と 3 が利用可能である場合、WAR がバージョン 3 を使用してしまうのを防ぐことはできません。その結果、WAR がバージョン 2 のパッケージを要求し、バージョン 3 とは互換性がない場合には、ランタイム・エラーが発生します。

11. 必要な場合にのみ Use-Bundle を使う

(WebSphere Application Server に特有のベスト・プラクティス)

WebSphere Application Server で OSGi アプリケーションを作成する場合のベスト・プラクティスは、シナリオを共有している特定のバンドルのサブセットにおいてのみ、Use-Bundle アプリケーション・マニフェスト・ヘッダーを指定することです。

その理由

WebSphere Application Server の Use-Bundle アプリケーション・マニフェスト・ヘッダーを利用すると、アプリケーションのデプロイメント・プロセスで、同じパッケージをエクスポートする複数のバンドルのうちの 1 つを他のバンドルよりも優先することができます。

実行時、OSGi アプリケーションは互いに隔離されていますが、それらの依存関係は共有されています。OSGi アプリケーションの Application-Content ヘッダーで指定されたバンドルは、独自の隔離された OSGi フレームワークで実行されます。依存関係はサーバーの共有バンドル空間で実行されます。

依存関係自体は OSGi アプリケーションをデプロイする際に決定されます。デプロイメントの際、アプリケーション・バンドルによってインポートされたパッケージは、アプリケーションの中にあるバンドルによってエクスポートされたパッケージ、または構成されたバンドル・リポジトリーの中にあるバンドルによってエクスポートされたパッケージと照合されます。バンドル・リポジトリーの中のバンドルが必要な場合には、そのバンドルがサーバーに対してプロビジョニングされます。パッケージのバージョンによる制約のために、共有バンドル空間で同じパッケージを提供する異なるバンドルを使って実行するように、2 つのアプリケーションをデプロイし、構成することができます。これが唯一問題になるのは、2 つのアプリケーションが、問題となるパッケージのクラスのインスタンスを使って相互作用する必要がある場合です。この場合には、2 つのアプリケーションがそのパッケージの同じバンドルに接続されていることを確実にするために、Use-Bundle アプリケーション・マニフェスト・ヘッダーが使用されなければなりません。

アプリケーション間での依存関係の共有を実現するために Use-Bundle を指定する必要はありません。Use-Bundle を指定する必要があるのは、2 つのアプリケーションが、同じバージョンの 1 つのクラスを共有し、そのクラスを提供する同じバンドルに 2 つのアプリケーションを確実に接続する必要がある場合のみです。

例えば、バンドル X を含むアプリケーションをデプロイするとします。バンドル X はバージョン 1.0 またはそれ以上、ただしバージョン 2.0 を含まない org.hal.a パッケージをインポートします (図 13)。この意味を OSGi のセマンティック・バージョン管理に従って考えると、X は org.hal.a をエクスポートする任意のバンドルに接続でき、この API を使用する側の観点から見る限り API の大幅変更はないということです。ここでは、API.A と呼ばれる 1 つのバンドルのみが、バージョン 1.0 で org.hal.a をエクスポートします。つまりバンドル X は API.A に接続されます。したがって、バンドル X にはバージョン 1.0 の org.hal.a の実装が見えます。Implementation.A はそうした実装の 1 つです。


図 13. バンドル X が受け入れ可能なバージョンの org.hal.a を提供するために、OSGi がバンドル X と API.A を接続する

次に、バンドル Y を含むアプリケーションをデプロイします (図 14)。バンドル Y は、バージョン 1.5 またはそれ以上、ただしバージョン 2.0 を含まない org.hal.a パッケージをインポートします。また、バージョン 1.5 で org.hal.a パッケージをエクスポートする API.B もデプロイされます。バンドル Y はより新しいバージョンの org.hal.a をインポートするので、バンドル Y を API.A に接続することはできませんが、バンドル Y を API.B に接続することはできます。Implementation.B バンドルはバージョン 1.5 の org.hal.a の実装を提供し、バージョン 1.5 またはそれ以上、ただしバージョン 1.6 を含まない org.hal.a をインポートします。OSGi Alliance Semantic Versioning technical whitepaper には、この背景にある理由が詳細に説明されています。


図 14. バンドル Y が受け入れ可能なバージョンの org.hal.a を提供するために、OSGi がバンドル Y と API.B を接続する

次に、バンドル Z を含む 3 番目のアプリケーションをデプロイします。バンドル Z は、バンドル X と同じバージョン範囲 (バージョン 1.0 またはそれ以上、ただし 2.0 を含まない) の org.hal.a パッケージをインポートします (図 15)。バンドル Z の作成者は バンドル Z が Implementation.A を利用することを望んでいますが、API.B はバージョン 1.5 (バンドル Z のインポート範囲内) の org.hal.a をエクスポートするため、バンドル Z は API.B に接続され、したがって Implementation.B しか見ることができません。


図 15. バンドル Z は API.B に接続され、したがって Implementation.A を見ることができない

バンドル Z が API.A に確実に接続されるようにするためには、バンドル Z は Use-Bundle アプリケーション・マニフェスト・ヘッダーに API.A と指定する必要があります。するとバンドル Z は (バンドル Z の作成者が意図したとおり) Implementation.B ではなく Implementation.A を見ることができるようになります。


図 16. バンドル Z が API.A に接続され、Implementation.A が見えるようになる

12. パーシスタンス・バンドルを使用してパーシスタンス・ユニットを共有する

アプリケーションの中で JPA を使用する場合には、バンドルを OSGi のパーシスタンス・バンドルとしてパッケージ化します。クライアントが直接 EntityManagerFactory を使用しない場合には、データ・アクセス・サービスを OSGi サービス・レジストリーの中で公開するようにし、パーシスタンス・バンドルからエンティティー・クラスをエクスポートしてはいけません。

その理由

WebSphere Application Server の OSGi アプリケーション・フィーチャーは、OSGi の JPA サービス仕様に準拠する OSGi パーシスタンス・バンドルをサポートしています。JPA によって管理されるクラスと persistence.xml とを OSGi のパーシスタンス・バンドルにパッケージ化することで、容易に共有可能な JPA リソースを持つ再利用可能なモジュールを作成することができます。このモジュールは WebSphere Application Server の OSGi ランタイムで使用することができ、また管理されない JPA サービス実装で使用することができます。また、OSGi ベースの多数のパーシスタンス・クライアントでパーシスタンス・バンドルを共有することもでき、パーシスタンス・クライアントを含めないことで、コードは凝集度が高まり、再利用しやすくなります。必ず Meta-Persistence バンドル・マニフェスト・ヘッダーを指定し、またパーシスタンス記述子にバンドル内のすべてのパスを指定することを忘れないようにします。

パーシスタンス・ユニットが従来の WAR の中にパッケージ化されている場合には、そのパーシスタンス・ユニットを別の OSGi バンドルとして分割する必要があります。WAR の中にあるパーシスタンス・ユニットは Java EE コンテナーによって管理され、OSGi フレームワークの中では共有されません。したがって、WAR の中にあるパーシスタンス・ユニットを OSGi アプリケーションの中の別の OSGi バンドルで使用することはできません。WAR からパーシスタンス・ユニットを削除できない場合には、Blueprint コンテナーや OSGi サービス・レジストリーを使ってそのパーシスタンス・ユニットにアクセスすることはできない、ということを忘れないでください。

他のアプリケーション・コードからパーシスタンス・バンドルを分離した方が良いもう 1 つの理由は、前述のベスト・プラクティスで説明されています。いくつかのアプリケーションがデータベース内のデータにアクセスする必要がある場合、それらのアプリケーションは、同じエンティティー・マッピングを再利用する方が理にかなっています。そうすることで、両方のアプリケーションが同じデータ・マッピングを共有するため、データベース内のデータ破損を防ぐことができ、さらに、将来何らかのスキーマ変更があった場合でも、1 つのバンドルの更新が必要となるだけです。パーシスタンス・ユニットが大規模なバンドルの中にパッケージ化されている場合には、複数のアプリケーションの間でエンティティーを容易に共有することはできず、必然的にコードや保守の重複が生じます。

13. 提供されているコンポーネント・モデルを最大限に利用する

(WebSphere Application Server に特有のベスト・プラクティス)

OSGi、WebSphere Application Server の OSGi アプリケーション・フィーチャー、および SCA の間には、この順序で粒度が粗くなる以下のような一連のコンポーネント・モデルが提供されています。

  • Blueprint を使用して、OSGi バンドルの中に細粒度のコンポーネントを定義します。
  • 特定のアプリケーション機能を提供するバンドルの集合として、OSGi アプリケーションを定義します。
  • SCA を使って 1 つの OSGi アプリケーションから別の OSGi アプリケーションにサービスを公開し、また通常の Java EE アプリケーションとの間でサービスをやり取りします。

その理由

Blueprint を使用することで、細粒度のコンポーネントを管理したり、他の OSGi バンドルとのやり取りを管理したりすることができます。バンドルの凝集度を高く (通常は小さいが)、依存関係の結合度を低く保つ必要があります。凝集度を高くし、結合度を低くする原則は、さまざまなバンドルをグループ化してエンタープライズ・バンドル・アプリケーションにする場合にも当てはまります。

OSGi アプリケーションは、従来の Java EE エンタープライズ・アプリケーションとほとんど同じであると考えることができます。アプリケーションを組み立てる際には、WebSphere Application Server が、Application-Content に記載されているバンドルを独自の隔離されたフレームワークにデプロイする、ということを忘れないでください。すべてのアプリケーションの依存関係のバンドルは、1 つの共有バンドル空間にデプロイされます。したがって、共通のコード・ライブラリーやサービスを共有の依存関係のバンドルの中にファクタリングすることが推奨されます。こうすることで、メモリーを節約でき、再利用が促進され、システムの管理が容易になります。所与の OSGi アプリケーションの Application-Content に記載されたバンドルは、そのアプリケーション特有のパーシスタンス・ロジック、ビジネス・ロジック、およびプレゼンテーション・ロジックのみで構成されていなければなりません。

必要な作業を OSGi アプリケーションにする方法は 2 つあります。最初の方法は HTTP を使って WAB にする方法です。2 番目の方法は Application-ExportService ヘッダーに記載されているサービスを呼び出す方法であり、このためには SCA を使用する必要があります。

利用可能なコンポーネント・モデルの中で、SCA は最も粒度の粗いモデルです。SCA によって分散プログラミング・モデルが実現され、値渡しのセマンティクスを強制することができます。SCA を使って 1 つの OSGi アプリケーションから別の OSGi アプリケーションにサービスを公開し、また通常の Java EE アプリケーションとの間でサービスをやり取りします。Rational Application Developer 8 には、OSGi アプリケーションを SCA コンポーネントとして作成、統合するためのツールのサポートが用意されています。

14. 複雑な作業はコンテナーに任せる

(WebSphere Application Server に特有のベスト・プラクティス)

サービスを管理するコードを作成するよりは、むしろコンテナー・サービスを使ってアプリケーションを構築し、エンタープライズ品質のサービスを提供します。

その理由

アプリケーション・プログラマーは、複雑な問題を堅牢で信頼性の高い方法で解決しようとし、エンタープライズ・サービス (トランザクションやマネージド・リソースなど) を利用することで、彼らに必要なサービス品質を実現しようとします。しかし多くの場合、こうしたサービスのコントロールを完全にコンテナーに任せることに対し、何らかのためらいがあるものです。これはコントロールを失うことで柔軟性も確実に失うためです。その結果、多くのアプリケーションでは、独自にリソースとライフサイクルを管理する選択がされています。

コントロールの反転、特に依存性注入は、アプリケーション開発を単純化する信じられないほど強力なツールです。しかし、アプリケーション開発はその核心として、コンテナーがライフサイクルやリソースを管理するという事実に依存しています。Blueprint の Bean のすべてのメソッドに対して宣言型のトランザクションを適用するためには XML では 1 行のコードしか必要ありませんが アプリケーションの中で同じ結果を実現するためには、メソッドごとに何十行ものコードが必要です。同様にリソース管理の場合も、Blueprint のリソース参照を使うことで、アプリケーションの中に直接リソースを注入することができ、またアプリケーションの中にセキュリティー・クレデンシャルを提供する必要がないように、セキュリティー・クレデンシャルを使ってアプリケーションを構成することもできます。開発者が独自にリソースを配置することを選択すると、コンテナーがアプリケーションを認証することはできず、クレデンシャルはアプリケーションの中に保存され、クレデンシャルが失効した場合にはアプリケーションを変更しなければなりません。

あるバンドルが JPA ベースのデータ・アクセス・サービスを提供していますが、コンテナーのサービスは何も使用していないとします。このバンドルは、トランザクションや EntityManager のライフサイクル、サービスの登録などを手動で管理しなければなりません。そのためには約 100 行のコードが必要であり、またリソースをクリアーするために、いくつもの try/finally ブロックを必要とします。クライアントも OSGi の API を使ってサービスを参照しなければならず、それによってさらにライフサイクル管理と try/finally ブロックが必要になります。またサービスの登録や利用に Blueprint が使われていないため、このサービスを利用できないエラー・ケースをアプリケーションが処理しなければなりません。また、サービス・ベースの自動プロビジョニングもありません。

宣言型のトランザクション、Blueprint、および管理された JPA を使用することで、複雑なライフサイクル管理やエラー管理のための何百行ものコードが不要になり、アプリケーションのサイズは小さくなります。こうすることで、アプリケーションの潜在的な欠陥の数も減ります。アプリケーション、およびこのデータ・アクセス・サービスを今後利用するすべてのアプリケーションは、サービス・ベースの依存性プロビジョニングを活用できるようになります。


まとめ

この記事では、OSGi バンドルを作成する際に、また WebSphere Application Server で OSGi アプリケーションを作成する際に、バンドル内の凝集度を高め、バンドル間の結合度を低くするベスト・プラクティスをいくつか説明しました。こうしたベスト・プラクティスを採用することで、OSGi アプリケーション用のフィーチャー・パックと JPA 2.0 用のフィーチャー・パックを持つ WebSphere Application Server V7 で実行されている OSGi 技術を使って、保守性と拡張性の高いアプリケーションを作成することができるようになります。


参考文献

学ぶために

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

議論するために

著者について

Author photo

Graham Charters はイギリスにある IBM の Hursley 開発研究所の Senior Technical Staff Member です。彼は現在、WebSphere Application Server 製品の業務に就いており、OSGi を WebSphere の顧客にどのように周知させるかを決めています。彼は IBM Application and Integration Middleware 部門で OSGi Alliance Expert Groups の技術リーダーです。彼は Apache Aries インキュベーター・プロジェクト管理委員会のメンバーでもあり、コミッターでもあります。

Author photo

Jeremy Hughes はイギリスにある IBM の Hursley 開発研究所で WebSphere Application Server の OSGi アプリケーション・フィーチャーの業務を行うランタイム・アーキテクトです。彼は 2001年から WebSphere Application Server の開発チームで Web サービスや OSGi 技術、Apache オープンソース・プロジェクトに関する業務を行ってきました。彼は Apache Aries インキュベーター・プロジェクトのコミッターであり、PPMC メンバーでもあります。

Author photo

Tim Mitchell は IBM の Hursley 研究所で開発者として働いています。彼は Web Services Gateway など、IBM のいくつかの Web サービス技術に関して数年間業務を行ってきました。彼は現在、WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発を行っています。

Author photo developerWorks 貢献著者レベル

Alasdair Nottingham は IBM による WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発リーダーです。彼はイギリスにある IBM の Hursley 開発研究所で働いています。彼は 2001年から WebSphere Application Server 開発チームでメッセージング、セキュリティー、OSGi などの技術に関する業務を行ってきました。彼は OSGi Alliance 標準化組織に積極的に参加しており、また Apache Aries インキュベーターのコミッターであり、PPMC メンバーでもあります。

Author photo

Mark Nuttall は IBM のソフトウェア技術者であり、1997年から IBM に勤務しています。彼は現在、最近リリースされた WebSphere Application Server の OSGi アプリケーション・フィーチャーの開発者であり、Apache Aries プロジェクトのコミッターでもあります。彼は IBM に入社して 1999年に Pervasive Computing 部門に異動して以来、OSGi 技術に関心を持っています。

Photo: Zoe Slattery

Zoe Slattery はイギリスの IBM Hursley に勤務する技術エバンジェリストです。彼女の現在の関心事項はエンタープライズ OSGi であり、特に Apache Aries でのオープンソースの OSGi コンポーネントの開発に関心を持っています。彼女はこれまで IT 業界の多くの分野で働いてきました。彼女は最初 FORTRAN プログラマーとして数値演算用の並列システムを扱い、また European Centre for Medium Range Weather Forecasts のためのデータ・アーカイブを管理しました。彼女は監督者として、IBM の Java 仮想マシンや Java クラス・ライブラリーのオープンソース実装の開発チームを指揮してきました。最近では、PHP 用テスト・ケースの開発に貢献し、PHP 用コア・テスト・ケースの数を 2 倍以上に増やしました。

Author photo

Tim Ward は WebSphere Application Server の OSGi アプリケーション・フィーチャーの設計と開発のリーダーです。彼は OSGi のEEG (Enterprise Expert Group) に積極的に参加しており、そこで OSGi JPA サービス仕様を共同で作成しました。現在はいくつかの RFC を指揮しています。彼は Apache Aries のコミッターでもあり、JPA の推進者でもあり、Spring Framework に関する IBM のキー・エキスパートの 1 人でもあります。

不正使用の報告のヘルプ

不正使用の報告

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


不正使用の報告のヘルプ

不正使用の報告

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


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=548869
ArticleTitle=OSGiアプリケーションを開発、利用するためのベスト・プラクティス
publish-date=07142010
author1-email=charters@uk.ibm.com
author1-email-cc=
author2-email=hughesj@uk.ibm.com
author2-email-cc=
author3-email=tim_mitchell@uk.ibm.com
author3-email-cc=
author4-email=not@uk.ibm.com
author4-email-cc=
author5-email=mnuttall@uk.ibm.com
author5-email-cc=
author6-email=zoe@uk.ibm.com
author6-email-cc=
author7-email=timothy.ward@uk.ibm.com
author7-email-cc=

タグ

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

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

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

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

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