WAR モジュール内の EJB コンテンツ

このトピックでは、Web アプリケーション・アーカイブ (WAR) モジュール内に Enterprise JavaBeans (EJB) コンテンツをパッケージするための 要件について説明します。

サポートされる EJB コンテンツ

明示的に規定されている制限を除いて、EJB Java™ アーカイブ (JAR) モジュール内部にパッケージされた Bean に対してサポートされる EJB 機能は、WAR モジュール内部にパッケージされた Bean に対してもサポートされます。 WAR モジュール内部にパッケージされた Bean は、EJB JAR モジュール内部にパッケージされた Bean と同じ動作を実行できます。

EJB 2.x および 1.x のセッション Bean と同様に、すべてのタイプの EJB 3.x Bean が、WAR モジュール内で サポートされます。完全な詳細説明については、EJB 3.1 仕様を参照してください。

パッケージ化のメカニズム

WAR モジュール内に EJB コンテンツをパッケージすることに関する規則は、 JAR モジュール内に EJB コンテンツをパッケージする場合の規則とは異なります。

Bean クラス・ファイルは、WAR モジュール内の以下の 2 つのロケーションのいずれかに 置かれる必要があります。
  • WEB-INF/classes ディレクトリー構造内に疎に
  • WEB-INF/lib ディレクトリー内に置かれた JAR ファイル内に

例えば、Bean クラス com.foo.MyBean を、 次のロケーションで WAR モジュール内に疎に置くことができます: WEB-INF/classes/com/foo/MyBean.class

あるいは、この Bean クラスを myJar.jar ファイル内に置き、 その後でそのファイルを次のロケーションに置くことができます: WEB-INF/lib/myJar.jar

WAR モジュールの一部の Bean コードが WEB-INF/classes ディレクトリー構造内に疎に置かれるようにし、 他の Bean コードが WEB-INF/lib ディレクトリー内の JAR ファイル内部に置かれるようにできます。 また、WAR モジュールのすべての Bean コードを WEB-INF/lib ディレクトリー構造内 に置き、WEB-INF/lib ディレクトリーには何も入れないという方法や、 すべての Bean コードを WEB-INF/lib ディレクトリー内の JAR ファイルに入れ、 WEB-INF/classes には何も置かないようにする方法も有効です。

複数の JAR ファイルを WEB-INF/lib ディレクトリーに置き、それらの ファイルのすべてが Bean コードを含んでいる可能性があるという状況も有効です。

同じ Bean クラスが、WEB-INF/classes ディレクトリー構造内に疎に 置かれていて、WEB-INF/lib ディレクトリー内の JAR ファイル内にも置かれている場合、 WEB-INF/classes ディレクトリー構造内に疎に置かれているクラスのインスタンス がロードされ、WEB-INF/lib ディレクトリー内の JAR ファイル内に置かれたインスタンスは 無視されます。

WEB-INF/lib ディレクトリー内の 2 つの異なる JAR ファイル内に同じ Bean クラスが置かれている場合、 クラスのどちらのインスタンスがロードされ、どちらが無視されるのかは 不明です。実行時に、サーバーは任意に一方のクラス・インスタンスを選出 してロードし、他方のクラス・インスタンスを無視します。

EJB デプロイメント記述子ファイルは WEB-INF ディレクトリー内に置かれる必要があります。 このディレクトリーには、ejb-jar.xml デプロイメント記述子と、すべての ibm-ejb-jar-ext XML または XMI 拡張ファイルおよび ibm-ejb-jar-bnd XML または XMI バインディング・ファイルが含まれます。 WEB-INF/lib ディレクトリー内の JAR ファイル内部に置かれた EJB 記述子ファイルは 無視されます。 EJB JAR モジュールと同様、各 EJB 記述子ファイルについて、0 個または 1 個のインスタンス がある可能性があります。どの EJB 記述子ファイルでも、複数のインスタンスが 存在することはできません。これには、persistence.xml ファイル は (存在する場合) 含まれません。Java Persistence API 仕様 によって、persistence.xml ファイルが存在する 場合、そのファイルは、WAR モジュールの WEB-INF/classes ディレクトリーにあるか、 または、WAR モジュールの WEB-INF/lib ディレクトリー内の JAR ファイルの中にある、 META-INF ディレクトリー内に置く必要があります。以下に例を示します。
  • WEB-INF/classes/META-INF/persistence.xml
  • WEB-INF/lib/MyEntity.jar
MyEntity.jar には META-INF/persistence.xml が含まれています。
ejb-jar.xml ファイルが WEB-INF/lib ディレクトリー内の JAR ファイルに配置されている場合、警告メッセージが表示されます。 以下に例を示します。
IWAE0068W ライブラリー・アーカイブ foo.jar ファイル内の EJB デプロイメント記述子 META-INF/ejb-jar.xml は無視されます。本製品はこのライブラリー・アーカイブ内の META-INF/ejb-jar.xml デプロイメント記述子を処理しません。META-INF/ejb-jar.xml デプロイメント記述子をライブラリー・アーカイブから WAR モジュール内の WEB-INF ディレクトリーに移動してください。

EJB コンテンツを組み込むには、WAR モジュールのバージョンが 2.5 以降である必要があります。バージョン 2.4 以前の WAR モジュール内に置かれた EJB コンテンツは無視されます。

トラブルの回避 (Avoid trouble) トラブルの回避 (Avoid trouble): WAR モジュールがバージョン 2.5 以降の場合、バインディングおよび拡張情報が含まれる Web メタデータ・ファイルは、XMI バージョンではなく、XML バージョンのファイルを使用する必要があります。gotcha

WAR ファイル内にパッケージされたエンタープライズ Bean の技術的相違点

次のリストには、WAR モジュール内にパッケージされた Bean と、EJB JAR モジュール内にパッケージされた Bean の間に存在する主要な技術的相違点が含まれます。

  • 共有コンポーネント名前空間

    1 つの WAR モジュール内のすべてのコンポーネントは、単一のコンポーネント名前空間 を共有します。これは、各 EJB コンポーネントが、単一のコンポーネント名前空間を、 WAR ファイル中の他のすべての EJB コンポーネントおよび非 EJB コンポーネント (サーブレットなど) と 共有することを意味します。対照的に、EJB JAR モジュール内にパッケージされた EJB コンポーネント は独自の専用コンポーネント名前空間を持っていて、他の どのコンポーネントとも共有しません。

    共有されるコンポーネント名前空間による重要な影響があります。 第一に、1 つのコンポーネント (EJB または非 EJB) が参照を宣言し、 別のコンポーネントがコンポーネント名前空間内を検索して その参照を探すことができることです。第二に、1 つのコンポーネントによって宣言された参照が、 別のコンポーネントで宣言された参照と競合する可能性があることです。対照的に、EJB JAR モジュール内に パッケージされた EJB は、コンポーネント名前空間内を検索して、別の EJB または非 EJB コンポーネントで宣言された 参照を探すことはできず、EJB で宣言された参照が、他のコンポーネントで宣言された参照と コンポーネント名前空間内で競合することは、それらの参照が同じ名前であってもあり得ません。

    共有名前空間を使用する場合、同じ参照が複数回宣言されることは、 それらの参照宣言が互いに競合しない限りは有効 です。それらの参照宣言が競合しない場合、 サーバーは参照が 1 回だけ宣言されているかのように 動作します。

    参照宣言が競合する 場合、エラー・メッセージが発行され、アプリケーションの開始は 失敗します。競合する参照ごとに警告メッセージが発行されます。 警告メッセージには、競合する参照の名前と、 その参照に割り当てられた複数の値が示されます。すべての警告メッセージ が発行された後、例外がスローされます。

  • EJB 記述子ファイルのロケーション

    ejb-jar.xml デプロイメント記述子ファイルおよび他の記述子ファイルは、WAR の WEB-INF ディレクトリー内に置かれる必要があります。 WEB-INF/lib ディレクトリー内の JAR ファイル の META-INF ディレクトリー内も含め、 WAR 内のそれ以外の場所にある EJB 記述子ファイルのインスタンスは無視されます。

  • アノテーションがスキャンされるかどうかの判別

    アノテーションを探すためにスキャンを実行するかどうかの 判別規則は、EJB JAR モジュールの場合と WAR モジュールの場合とで異なります。すべての規則の説明については、 『EJB 3.x モジュール・パッケージ化の概要』トピックを参照してください。

  • クラス・ロードおよび可視性

    WAR モジュール内にパッケージされた EJB クラスの最も一般的な使用パターンは、同じモジュール内にパッケージされた Web コンポーネントからのローカル・メソッド呼び出しです。 ただし、これらの EJB クラスには、リモート・メソッド呼び出しまたは他のモジュール内のクライアントによってアクセスすることもできます。 これらの場合、WAR モジュール内にパッケージされた EJB クラスの可視性の規則を理解することが重要です。 可視性の規則は、JAR モジュール内にパッケージされた EJB クラスと比較したときに異なります。

    リモート EJB メソッド呼び出しの場合、WAR モジュール内に EJB クラスをパッケージしたことによりもたらされる可視性の違いはありません。 EJB は、グローバル名前空間にバインドされ、他のモジュールのコンポーネントから検索したり、それらに注入することができます。 リモート・クライアントは、適切なスタブ・クラスを使用してメソッド呼び出しを行う必要があります。 スタブ・クラスの生成については、このトピックのセクション『スタブ生成』で説明しています。

    他のモジュールのコンポーネントからのローカル EJB メソッド呼び出しの場合は、EJB が WAR モジュール内にパッケージされるため、可視性の違いがあります。 これらの可視性の違いは、考慮する必要のあるクラス・ローダーの影響があるために発生します。

    アプリケーション全体のすべての EJB JAR モジュール内にパッケージされたコンテンツが、単一のアプリケーション・クラス・ローダー・インスタンスによってロードされます。

    対照的に、1 つの WAR モジュール内にパッケージされたすべての コンテンツは、その WAR モジュールに固有のクラス・ローダー・インスタンスで ロードされます。すべての EJB JAR コンテンツをロードするのに使用される単一のアプリケーション・クラス・ローダー・インスタンスは、WAR コンテンツをロードするのに使用される各クラス・ローダー・インスタンスの親です。

    クラスの可視性 は、クラスをロードしたクラス・ローダー・インスタンスに影響されます。 クラス・ローダー・インスタンスから可視なのは、そのインスタンス自体 または親クラス・ローダーがロードしたクラスです。しかし、 クラス・ローダー自体がロードしたのではなく、親の 1 つがロードしたのでもないクラスは、そのクラス・ローダーから可視ではありません。

    結果として、ある WAR モジュールに固有のクラス・ローダーによってロードされた クラスにとって、EJB JAR モジュール内のクラスは可視ですが、 別の WAR モジュール内のクラスは可視ではありません。EJB JAR モジュール 内のクラスにとっては、どの WAR モジュール内のクラスも可視ではありません。例えば、EJB JAR モジュール ejb3.jar 内部にパッケージされた EJB コンテンツ があり、ejb1.jar ファイル および ejb2.jar ファイル内部にパッケージされた EJB コンテンツもあるとします。この場合、次のようになります。
    • ejb1.jar ファイルおよび ejb2.jar ファイル が EJB JAR モジュールとしてインストールされている場合、ejb1.jar ファイル、ejb2.jar ファイル、 および ejb3.jar ファイル内部のコンテンツは、すべて同じ クラス・ローダー・インスタンスでロードされ、アプリケーション内の他の EJB JAR モジュール をロードするのにもそのインスタンスが使用されます。このケースでは、これら 3 つのすべての JAR ファイル 内のクラスは、すべて同じクラス・ローダー・インスタンスによってロードされるため、 互いに可視です。
    • ejb1.jar ファイルおよび ejb2.jar ファイルが両方とも、ある 1 つの WAR ファイルの WEB-INF/lib ディレクトリー内にパッケージされている場合、ejb1.jar ファイルおよび ejb2.jar ファイル内部のコンテンツは、単一のクラス・ローダー・インスタンスによってロードされます。 ただし、このクラス・ローダーは、ejb3.jar ファイルおよびアプリケーション内の他の EJB JAR のコンテンツのロードに使用されるクラス・ローダーと同じではありません。 このケースでは、ejb1.jar ファイルおよび ejb2.jar ファイル内のクラスは互いに可視であり、ejb3.jar ファイル内のクラスも可視です。 ejb3.jar ファイル内のクラスからは、ejb1.jar ファイルまたは ejb2.jar ファイル内のクラスは可視ではありません。
    • ejb1.jar ファイルが firstWar.war ファイルの WEB-INF/lib ディレクトリー内に パッケージされていて、ejb2.jar ファイルが secondWar.war ファイル の WEB-INF/lib ディレクトリー内にパッケージされている場合、 ejb1.jar ファイル内のコンテンツは 1 つのクラス・ローダー・インスタンスでロード され、ejb2.jar ファイル内のコンテンツは 2 つ目の クラス・ローダー・インスタンスでロードされ、ejb3.jar ファイル内のコンテンツおよび アプリケーション内の他のすべての EJB JAR は 3 つ目のクラス・ローダー・インスタンスで ロードされます。このケースでは、ejb1.jar ファイル および ejb2.jar ファイル内のクラスは互いに可視ではありませんが、 それらのクラスから ejb3.jar ファイル内のクラスは可視です。 ejb3.jar ファイル内のクラスからは、 ejb1.jar ファイルまたは ejb2.jar ファイル内のクラスは可視ではありません。
    これらのクラス・ローダーが複雑になるのを回避する 1 つの戦略は、共有ライブラリー内に EJB インターフェース・クラスをパッケージすることです。
    ベスト・プラクティス ベスト・プラクティス: 同じクラスを同じアプリケーション内の EJB JAR モジュールと WAR モジュールの両方にパッケージしないようにしてください。 同じアプリケーション内の 複数のロケーションに同じクラスをパッケージすると、クラスのどのインスタンスが 実行時にロードされ使用されるのかに関して混乱が生じることがあります。この区別は、 2 つの .class ファイルが、同じクラスの異なるバージョンを表している 場合に問題になることがあります。このようなシナリオを避けるには、.class ファイルを 1 つのロケーションにのみ パッケージするか、クラスのパッケージ構造を変更して、WAR モジュール内部にパッケージされた クラスの完全修飾名が、EJB JAR モジュール内部にパッケージされたクラスの完全修飾名と異なるように します。bprac
  • アプリケーション・プロファイルの拡張

    アプリケーション・プロファイルの拡張は、WAR モジュール内にパッケージされる EJB クラスに対してはサポートされていません。

スタブ生成

EJB メソッドのリモート・アクセスは、クライアント・サイドのスタブ・クラスの使用を 必要とします。ほとんどのクライアント環境で、製品ランタイムは必要なスタブ・クラスを自動的に生成します。 例外の 1 つに、シン・クライアント環境があります。 シン・クライアントでは、スタブ・クラスはクライアントを使用して手動で生成およびパッケージする必要があります。

EJB のバージョンに関係なく、EJB コンテンツが WAR モジュール内にパッケージされている場合、createEJBStubs ツールを使用してスタブを生成します。

詳しくは、トピック『スタブ作成コマンド』を参照してください。

トラブルの回避 (Avoid trouble) トラブルの回避 (Avoid trouble): WAR モジュールで EJB 2.1 クラスをパッケージする場合、EJBDeploy ツールによって生成されたスタブ・クラスを含めないでください。 これらのスタブ・クラスは、製品ランタイムによって自動的に生成されたスタブ・クラスとは異なり、障害が発生する場合があります。 多くの場合、自動生成されたスタブ・クラスで十分です。 例外は、Web モジュール内のコンポーネントが、別の JAR モジュール内にパッケージされた EJB 2.1 クラスでリモート・メソッド呼び出しを行う必要がある場合です。 この場合、他の JAR モジュールの EJB に対して EJBDeploy が生成したスタブ・クラスは、WAR モジュール内にパッケージする必要があります。gotcha

WAR モジュール内の EJB 2.x および 1.x コンテンツ

エンティティー Bean を除いて、EJB 2.x および 1.x コンテンツが WAR モジュール内で サポートされます。

WAR ファイル内にパッケージされた 2.x または 1.x モジュールは、 WAR モジュールの WEB-INF ディレクトリー内に、バージョン 2.x または 1.x の ejb-jar.xml デプロイメント記述子 を必要とします。XMI バインディング・ファイルおよび拡張ファイルが存在する場合、これらのバインディングおよびファイルも WAR モジュールの WEB-INF ディレクトリー内にパッケージする必要があります。

2.x または 1.x コーディング・スタイルに従って実装したセッション Bean および メッセージ駆動型 Bean は WAR モジュール内部にパッケージできます。

Bean 管理パーシスタンス (BMP) およびコンテナー管理パーシスタンス (CMP) エンティティー Bean は、 両方とも WAR モジュール内ではサポートされません。

アプリケーション・プロファイルおよびアクセス・インテント・サービスは、WAR モジュールではサポートされていません。 WAR モジュールで見つかる セッション Bean は、アプリケーション・プロファイル・タスクにアクセスできません。

3.x コーディング・スタイルと、2.x および 1.x コーディング・スタイルに従って実装した EJB コンテンツ を両方とも、単一の WAR モジュール内に一緒にパッケージ することができます。ただし、このケースでは、XMI バージョンではなく、XML バージョンのファイルを 使用して、バインディング情報および拡張情報を宣言する 必要があります。

EJB JAR モジュールから WAR モジュールへの既存 EJB コンテンツの移動

1 つの手法は、既存の EJB JAR ファイルを、WAR ファイルの WEB-INF/lib ディレクトリー内に 置くことです。その後、JAR ファイルの META-INF ディレクトリーから記述子ファイル を削除し、それらのファイルを WAR ファイルの WEB-INF ディレクトリーに 置きます。

2 つ目の手法は、EJB JAR ファイル内のクラス・ファイル を、WAR モジュール内の WEB-INF/classes ディレクトリーの 下の正しいロケーションに置くことです。その後、JAR ファイルの META-INF ディレクトリーから記述子ファイル を削除し、それらのファイルを WAR ファイルの WEB-INF ディレクトリー内に 置きます。

複数の EJB JAR モジュールを単一の WAR モジュール内に移動させる場合、 それらの EJB JAR モジュールの META-INF ディレクトリー 内で前に検出された記述子ファイルのそれぞれのコンテンツをマージし、 単一にまとめたバージョンの記述子ファイルにして、WAR ファイルの WEB-INF ディレクトリーに 置く必要があります。マージされる可能性がある記述子ファイルの例には、ejb-jar.xml、ibm-ejb-jar-bnd.xml、 ibm-ejb-jar-ext.xml、および ibm-ejb-jar-ext-pme.xml がありますが、これらに限定されるわけではありません。

単一のコンポーネント名前空間が WAR モジュール内のすべてで共有されるため、 WAR モジュール内のさまざまなコンポーネント (EJB および 非 EJB の両方) によって宣言された参照を 検査して、それらの参照が互いに競合しないことを確認する必要があります。

EJB JAR モジュールから WAR モジュールへ移動された XMI バインディング・ファイルおよび拡張ファイル内のいくつかの場所を変更し、META-INF/ejb-jar.xml への参照を削除し、それらを WEB-INF/ejb-jar.xml で置き換える必要があります。

EJB JAR モジュール内でサポートされるが WAR モジュール内ではサポートされない EJB 機能

以下の EJB 機能は、WAR モジュール内ではサポートされません。
  • BMP および CMP エンティティー Bean
  • EJB 3.1 より前のスタイルの開始 Bean
    重要: EJB 3.1 で定義されている singleton 開始 Bean はサポート されます。
エンティティー Bean が WAR モジュール内に置かれている場合、エラー・メッセージが表示され、アプリケーションの開始は失敗します。 例えば、FooApp アプリケーション内の foo.war モジュール内に foo エンティティー Bean が 置かれているとします。この結果、次のようなメッセージが発行されます。
CWMDF0025E: EJB Web アプリケーション・アーカイブ (WAR) モジュール内のエンティティー Bean は、EJB 3.1 仕様によって許可されていません。
WSVR0039E: EJB JAR foo.war を開始できません: EJB Web アプリケーション・アーカイブ (WAR) モジュール内のエンティティー Bean は、EJB 3.1 仕様によって許可されていません。
foo.war モジュール内の foo Bean をスタンドアロン EJB モジュールに移動する必要があります。WAR モジュール内の無効なエンティティー Bean の完全なリストを確認するには、ログを調べてください。

トピックのタイプを示すアイコン 概念トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=cejb_ejbinwar
ファイル名:cejb_ejbinwar.html