EJB 3.x モジュール・パッケージ化の概要
このトピックでは、Enterprise JavaBeans (EJB) 3.x Bean を使用する場合のアプリケーションのパッケージ化について説明します。
EJB 3.x Bean を使用するアプリケーションのパッケージ化は、 Java™ Platform, Enterprise Edition (Java EE) 1.4 アプリケーションのアセンブリー要件に似ています。コンポーネントはモジュールにパッケージ化され、モジュールはアプリケーション・エンタープライズ・アーカイブ (EAR) ファイルにパッケージ化されます。 コンポーネントおよびモジュールには、ともに、Extensible Markup Language (XML) デプロイメント記述子内で記述メタデータが提供されています。 EJB 3.x 仕様では、メタデータの記述およびパーシスタンス・ユニットのパッケージ化の追加のメソッドがサポートされています。
- EJB モジュール用の Java アプリケーション・アーカイブ (JAR) ファイル。 Java EE アプリケーション・クライアント・モジュールおよびユーティリティー・クラス・モジュール。
- Web モジュール用の Web アプリケーション・アーカイブ (WAR) ファイル、または EJB コンテンツ。 EJB コンテンツを組み込むには、WAR ファイルのバージョンが 2.5 以上である必要があります。
- リソース・アプリケーション・アーカイブ (RAR) ファイルなどのテクノロジー固有の他のモジュール、および他のタイプのモジュール。
デプロイメント記述子を使用しない EJB モジュール
EJB 3.x Bean を使用している場合は、デプロイメント記述子を使用せずに EJB モジュールをパッケージ化することができます。 これを実行するには、EJB コンポーネント内にあるアノテーションでメタデータを使用して JAR ファイルまたは WAR ファイルを作成する必要があります。 EJB 3.x Bean では、アノテーションを使用して定義したメタデータに関する項目を ejb-jar.xml ファイルに含める必要はありません。
EJB 3.0 の場合、デフォルトでは、EJB 3.0 モジュールのインストール中にアノテーションがスキャンされるようになっていました。 WebSphere® Application Server、 バージョン 8.5の場合、デフォルトでは、アプリケーションのインストール時またはサーバーの始動時にJava EE 5 より前のモジュールをスキャンしません。
Feature Pack for EJB 3.0 および Feature Pack for Web Services の両方との後方互換性を維持するために、既存の Web モジュールから追加メタデータをスキャンするかどうかを選択できます。 サーバー・レベルのスイッチは、各フィーチャー・パックのスキャン動作ごとに定義されます。 デフォルトが不適切な場合、デフォルトを変更する必要のあるそれぞれのサーバーおよび管理サーバーでスイッチを設定する必要があります。 スイッチは、サーバーのカスタム・プロパティー com.ibm.websphere.webservices.UseWSFEP61ScanPolicy={true|false} および com.ibm.websphere.ejb.UseEJB61FEPScanPolicy={true|false} です。 管理コンソールでこれらのプロパティーを定義するには、「
をクリックします。デプロイメント記述子を使用する EJB モジュール
デプロイメント記述子を使用する EJB モジュールを引き続き使用することができます。 デプロイメント記述子を使用するモジュールは、EJB 3.x を含む EJB 仕様のバージョン・レベルをサポートできますが、一般的にこれらの記述子は、モジュール内のコンポーネントの実装要件を反映している必要があります。
EJB モジュールは、EJB 3.x、2.x、または 1.x のデプロイメント記述子を持つことができます。
EJB 2.x または 1.x のデプロイメント記述子の場合、デプロイメント記述子にはモジュールの全メタデータが含まれていてアノテーション・メタデータの追加のスキャンが発生しないものと想定されています。
EJB コンテナー・アノテーション・スキャンは、デプロイメント記述子を持たない EJB モジュール、または EJB 3.0 スキーマ・レベルの ejb-jar.xml デプロイメント記述子を持ち、metadata-complete XML 属性が false に設定されているかまたは省略されている EJB モジュールに対して実行されます。 アノテーション・スキャンが実行されるかどうかを判別するためにサーバーで使用されるすべてのルールについては、『アノテーション・スキャンの動作』セクションを参照してください。
アノテーション・スキャンの動作
サーバーは、モジュールのクラス・ファイルを検査し、アノテーション・コンテキストを検索できます。 サーバーは、コンポーネント、リソースへの参照、または特定の動作を定義している可能性があるアノテーション・コンテキストを検索します。 例えば、EJB コンポーネントの定義、EJB コンポーネントが使用する必要があるデータ・ソースへの参照の宣言、または EJB メソッドに関連付けられているトランザクション属性またはセキュリティー属性の宣言に、アノテーションが使用されることがあります。 この検査プロセスは、「アノテーション・スキャン」と呼ばれます。 モジュール内のクラス・ファイルに、サーバーが準拠する必要があるアノテーションが含まれている場合、アノテーション・スキャンが実行されるようにサーバーを構成する必要があります。 モジュール内のクラス・ファイルにアノテーションが含まれていない場合は、パフォーマンス上の理由から、アノテーション・スキャンを実行しないようにサーバーを構成できます。
- ejb-jar.xml デプロイメント記述子ファイルが存在しているかどうか
- ejb-jar.xml デプロイメント記述子のバージョン (存在している場合)
- ejb-jar.xml デプロイメント記述子の metadata-complete 設定の値 (存在している場合)
- web.xml デプロイメント記述子のバージョン (EJB コンテンツが WAR モジュールにパッケージされており、ejb-jar.xml デプロイメント記述子が存在していない場合)
- web.xml デプロイメント記述子の metadata-complete 設定の値 (EJB コンテンツが WAR モジュールにパッケージされており、ejb-jar.xml デプロイメント記述子が存在しない場合)
EJB JAR モジュールまたは WAR モジュールにパッケージされている EJB コンテンツでアノテーションのスキャンを実行するかどうかを決定する方法を次の表に示します。
ejb-jar.xml | ejb-jar.xml の metadata-complete 値 | アノテーションをスキャンするかどうか |
---|---|---|
存在する (バージョン 2.x 以下) | 該当なし | いいえ |
存在する (バージョン 3.x 以上) | 真 | いいえ |
存在する (バージョン 3.x 以上) | false (または省略) | はい |
存在しない | 該当なし | はい |
ejb-jar.xml ファイル | ejb-jar.xml の metadata-complete 値 | web.xml ファイル | web.xml の metadata-complete 値 | アノテーションをスキャンするかどうか |
---|---|---|---|---|
存在する (バージョン 3.x 以上) | 真 | 該当なし | 該当なし | いいえ |
存在する (バージョン 3.x 以上) | false (または省略) | 該当なし | 該当なし | はい |
存在する (バージョン 2.x 以下) | 該当なし | 該当なし | 該当なし | いいえ |
存在しない | 該当なし | 存在する (バージョン 2.5 以上) | 真 | いいえ |
存在しない | 該当なし | 存在する (バージョン 2.5 以上) | false (または省略) | はい |
存在しない | 該当なし | 存在する (バージョン 2.4 以下) | 該当なし | いいえ |
存在しない | 該当なし | 存在しない | 該当なし | はい |
ejb-jar.xml デプロイメント記述子の ejb-jar エレメントの metadata-complete 属性と、アプリケーションまたはモジュールのインストール・プロセス時に指定される metadata-complete インストール設定の違いを理解しておくことが重要です。
ejb-jar.xml ファイルの ejb-jar エレメントの metadata-complete 属性は、XML 属性です。 この属性は、EJB コンテンツでのアノテーション・スキャンの表に示すルールに従って、クラスでアノテーション・データをスキャンする必要があるかどうかを判別するためにサーバーによって使用されます。
対照的に、インストール時に指定される metadata-complete 設定値は、サーバーが ejb-jar.xml ファイルを生成するために使用します。 モジュール内に ejb-jar.xml ファイルが存在しておらず、metadata-complete インストール設定に値 true が割り当てられている場合、サーバーはアノテーション・コンテンツをスキャンし、このコンテンツを使用して ejb-jar.xml ファイルを生成し、このファイルの metadata-complete XML 属性に値 true を設定します。
パーシスタンス・ユニット
persistence.xml ファイルおよびそれに関連付けられたクラスを含むパーシスタンス・ユニットは、それらが必要とされるモジュールにパッケージ化することができます。 また、 従属モジュールを使用して EAR ファイルにパッケージ化された、別のユーティリティー JAR ファイルに パッケージ化することもできます。
アプリケーションのパッケージ化
同じアプリケーション内で EJB 2.x 以前の Bean と EJB 3.x Bean を混在させることができます。 ただし、EJB 2.x または EJB 1.x モジュールでは EJB 3.x Bean は認識されません。
- アプリケーション名は、EAR ファイルの名前から EAR ファイル拡張子を除去したものであることが想定されます。
- .war で終わるファイルは、Web モジュールであると想定されます。 Web モジュールのコンテキスト・ルートは、アプリケーション・パッケージのルートに関連するファイルの名前から WAR ファイル拡張子を除去したものです。
- 最後が .jar で終わり、/lib ディレクトリー内になく、ejb-jar.xml ファイル、または @Stateful、@Stateless、@Singleton、または @MessageDriven アノテーションを定義する少なくとも 1 つのクラスのいずれかを含むファイルは、EJB モジュールであると想定されます。
- /lib ディレクトリー内にないその他の JAR ファイルは、EJB モジュールであるとは想定されません。
JPA パッケージ化
パーシスタンス・ユニットは、アクセス可能性および再利用可能性を高くするために、個別の JAR ファイルに パッケージ化することをお勧めします。 これらは、実際のデータベース・パーシスタンスが 発生するかどうかにかかわらず、コンテナーの外側でテストすることができます。 パーシスタンス・ユニットは、スタンドアロン・アプリケーション、またはユーティリティー JAR ファイルとして EAR ファイルに組み込むことができます。 大量のクラスをスキャンする際にはさまざまなユース・ケースおよび潜在的なパフォーマンス問題が存在するため、パーシスタンス・ユニットでそのクラスを定義することをお勧めします。
パーシスタンス・シナリオに使用されるセッション・ファサード
一般的なパターンでは、パーシスタンスのためにセッション・ファサードを使用します。 JPA を駆動するためのセッション Bean ファサードの使用は、サポートされています。 EntityManager インターフェースは スレッド・セーフではないため、サーブレットは @PersistenceContext を注入することができません。 サーブレットは、ファサード・パターンまたは EntityManagerFactory インスタンスのいずれかを使用して、各要求の EntityManager を作成する必要があります。
JPA パーシスタンス・ユニットは、セッション Bean ファサードとは別の JAR ファイルで定義することをお勧めします。 これは、共有の柔軟性を向上させるための ベスト・プラクティスであるだけではなく、JPA および JPA 以外の アノテーションを付けられたクラスが混合される問題も回避します。
一般的に、エンティティー・クラスおよび JPA persistence.xml 定義を保持するために JAR ファイルが作成され、ユーティリティー JAR ファイルとして EAR ファイルに追加されます。 EJB 3.x モジュールは、JAR ファイルへの従属を EJB 3.x モジュール MANIFEST.MF 内で宣言することによって追加します。 例えば、EAR に TradeApp.ear、TradeWeb.war、EJB3Trade.jar、および TradeInfo.jar ファイルが含まれている場合は、EJB3Trade.jar ファイルの MANIFEST.MF は、以下のようになります。
Manifest-Version: 1.0
Class-Path: TradeInfo.jar
EJB3Trade.jar ファイルのセッション・ファサードは、TradeInfo.jar ファイルの JPA エンティティー・クラスおよびパーシスタンス・ユニットを参照します。 TradeWeb.war ファイルで定義される Web アプリケーションでも同じことを行って、JPA エンティティー・オブジェクトを、Web 層と EJB コンテナー層の間のデータ転送オブジェクトとして処理することができます。
クロス層およびクロス・バージョン・セッション Bean 参照のシナリオ
EJB 3.x セッション Bean への参照を定義して使用するには、いくつかの方法があります。 EJB 3.x セッション間の場合は、@EJB 注入ターゲットが使用できます。 例えば、クロス層 (Web アプリケーションと EJB 3.x セッション)、またはクロス・バージョン (EJB 3.x セッションと EJB 2.1 セッション) の場合は、XML デプロイメント記述子参照を使用して ejb-refs および ejb-local-refs を定義することができます。 EJB 3.x ビジネス・インターフェースを参照するか、または EJBLocalHome も定義する EJB 3.x より前のコンポーネント・スタイルのインターフェースを参照するかに応じて、2 つのバリエーションがあります。 Web アプリケーションおよびクライアント・アプリケーションでは、参照するコンポーネントがオートリンクを使用して解決できる場合は、@EJB アノテーションも使用できます。
上のシナリオでは、EJB 3.x スタイルのセッション Bean 実装を使用する EJB 2.1 スタイルのクライアント・パターンが使用されます。 より新しいクライアント・スタイルの場合、クライアント・サイドをクリーンアップして、ホーム・インターフェースを通さずに直接セッション Bean ビジネス・インターフェースを検索させることができます。 この場合は、 @LocalHome(<localhome>.class) アノテーションを定義する必要はありません。 ejb-ref および ejb-local-ref の可変定義を使用して、これを実行することができます。 ローカル・ホーム・エレメント値に NULL 値を使用して、ejb-local-ref を ホーム・バインディングではなく、セッション Bean の ejblocal: バインディングにバインドします。 以下に例を示します。
<ejb-local-ref id="EJBLocalRef_1154112538064">
<description>com.ibm.persistence.ejb3.order.facadecom.ibm.persistence.ejb3.order.facade</description>
<ejb-ref-name>ejb/OrderEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home></local-home>
<local>com.ibm.persistence.ejb3.order.facade.OrderProcessor</local>
</ejb-local-ref>
また、検索されるオブジェクトに適したキャストを実行するように、クライアント・コードを調整する必要があります。 この場合は、 ホーム・インターフェースの代わりに、以下のビジネス・インターフェースを使用します。
try {
InitialContext ctx = new InitialContext();
orderProcessor = (OrderProcessor)ctx.lookup("java:comp/env/ejb/OrderEJB");
}
catch(Exception e) {
e.printStackTrace(System.out);
throw new ServletException(e);
}