Oracle® Fusion Middleware Oracle WebLogic Server Enterprise JavaBeansの開発 12c (12.1.2) E48054-02 |
|
前 |
次 |
この章では、EJB 3.1の一般的な実装プロセスを説明し、EJBをWebLogic Serverで実行する方法について説明します。
この章の内容は次のとおりです:
この節では、EJB 3.1の開発プロセスを簡単に説明します。主な実装タスクと関連する結果について説明します。
次の項の大部分では、EJB 3.1プログラミング・モデルについて説明しています。3.1と2.xでのプログラミング・モデルの相違点については、一部で簡単に触れているのみです。EJB 2.xに精通しており、2つのモデルの相違点について詳しく知りたい場合は、「EJBの新機能と変更された機能」を参照してください。
表4-1 EJB開発タスクと結果
# |
手順 | 説明 | 結果 |
---|---|---|---|
1 |
|
Javaソース・ファイルのディレクトリ構造を作成し、必要に応じてデプロイメント記述子を作成します。 |
ローカル・ドライブ上のディレクトリ構造 |
2 |
|
インタフェースを実装するJavaファイルを作成し、EJBの動作を記述するEJB 3.1メタデータ・アノテーションを含めます。 |
|
3 |
|
EJBを記述するインタフェースなしのビューまたはビジネス・インタフェースを作成します。 |
各インタフェースの |
4 |
|
必要に応じて、ビジネス・メソッド呼出しやライフサイクル・コールバック・イベントをインターセプトするインターセプタを記述したインターセプタ・クラスを作成します。 |
各インターセプタ・クラスの |
5 |
|
必要に応じて、タイマー・オブジェクトが時限イベントの時刻を過ぎたときに発生するコールバックをスケジューリングするタイマーを作成します。 |
メタデータの変更(自動タイマーの場合)またはクラスの変更(プログラムによるタイマーの場合)。 |
6 |
|
依存関係インジェクションまたはJNDIルックアップを使用してEJBの参照を取得します。 |
メタデータの変更(アノテーションの設定やデプロイメント記述子の設定)またはクライアントに対するコード変更。 |
7 |
|
コンテナ管理のトランザクションまたはBean管理のトランザクションをプログラミングします。 |
メタデータおよび場合によっては例外を処理するためのロジック(再試行ロジックまたは |
8 |
|
ソース・コードをコンパイルします。 |
各クラスおよびインタフェースの |
9 |
|
必要に応じて、EJB固有のデプロイメント記述子を作成します。この手順は、EJB 3.1プログラミング・モデルを使用する場合は不要です。 |
|
10 |
|
コンパイル済みのクラス(および、必要に応じてデプロイメント記述子)をデプロイメント用にパッケージ化します。 状況によっては、ファイルをアーカイブせずにディレクトリ形式で展開しておくことも可能です。 |
アーカイブ・ファイル(EJB JARまたはエンタープライズ・アプリケーションEAR)、または対応する展開済みディレクトリ |
11 |
|
選択したステージング・モードに従って、アーカイブまたはアプリケーション・ディレクトリのターゲットとして目的の管理対象サーバーまたはWebLogic Serverクラスタを設定します。 |
デプロイしたEJBでサービスを呼び出せます。 |
EJB 3.1モジュールをアセンブルするソース・ディレクトリを作成します。
ソース・ファイルと出力ファイルを並列ディレクトリ構造に分離する分割開発ディレクトリ構造をお薦めします。分割ディレクトリ構造を準備し、EJB 3.1をエンタープライズ・アプリケーション・アーカイブ(EAR)としてパッケージ化する方法については、『Oracle WebLogic Serverアプリケーションの開発』の分割開発ディレクトリ環境の概要に関する項を参照してください。
EJBをJARファイルにパッケージ化してデプロイする場合は、クラス・ファイル用のディレクトリを作成します。EJBデプロイメント記述子(EJB 3.1プログラミング・モデルでは、オプションですがサポートはされています)も使用する場合は、それをMETA-INF/ejb-jar.xml
としてパッケージ化できます。
例4-1 JARをパッケージ化するためのディレクトリ構造
myEJBjar/ META-INF/ ejb-jar.xml weblogic-ejb-jar.xml weblogic-cmp-jar.xml foo.class fooBean.class
詳細は、「JARでのEJBのパッケージ化」を参照してください。
EJBは、EJBクラスをWEB-INF/classes
という名前のサブディレクトリに入れるか、WEB-INF/lib
ディレクトリ内のJARファイルに入れることで、Webアプリケーション・モジュール(WAR)に直接パッケージ化することもできます。必要に応じて、EJBデプロイメント記述子も使用する場合は、それをWEB-INF/ejb-jar.xml
としてパッケージ化できます。
例4-2 WARをパッケージ化するためのディレクトリ構造
myEJBwar/ WEB-INF/ ejb-jar.xml weblogic.xml weblogic-ejb-jar.xml /classes foo.class fooServlet.class fooBean.class
注意: EJB 2.1エンティティBeanおよびEJB 1.1エンティティBeanは、WARファイル内ではサポートされません。これらのコンポーネント・タイプは、スタンドアロンの |
詳細は、「WARでのEJBのパッケージ化」を参照してください。
EJB Beanクラスは、EJBプログラミングの主要なアーティファクトで、EJBビジネス・インタフェースを実装し、EJBメタデータ・アノテーションを含みます。EJBメタデータ・アノテーションの用途としては、EJBコンテナへのセマンティクスおよび要件の指定、コンテナ・サービスの要求、アプリケーション・デプロイヤやコンテナ・ランタイムへの構造情報および構成情報の提供などがあります。
EJB 3.1プログラミング・モデルで必須なアノテーションは、EJBのタイプを指定する@javax.ejb.Stateful
、@javax.ejb.Stateless
、または@javax.ejb.MessageDriven
のいずれか1つのみです。他にもさまざまなアノテーションを使用してEJBを細かく構成できますが、それらのアノテーションには一般的なデフォルト値が設定されているため、デフォルト以外の動作を設定したい場合を除けば、Beanクラス内で明示的にそれらのアノテーションを使用する必要はありません。このようなプログラミング・モデルにより、一般的な動作を実行するEJBのプログラミングが非常に簡単になっています。
Beanクラスのプログラミングの詳細やサンプルについては、第5章「アノテーション付きEJBクラスのプログラミング」を参照してください。
クライアントは、インタフェースなしのビューまたはビジネス・インタフェースを介してエンタープライズBeanにアクセスします。
EJB 3.1のインタフェースなしのローカル・クライアント・ビュー・タイプでは、個別のローカル・ビジネス・インタフェースを必要とすることなく、ローカル・セッションBeanへのアクセスを提供して、コンポーネントでEJB Beanクラス・インスタンスを直接注入させることで、EJBの開発を単純化しています。
インタフェースなしのビューは、EJB 3.0ローカル・ビューと同様に動作します。たとえば、参照渡しのコールのセマンティクスおよびトランザクションやセキュリティ伝播などの機能をサポートします。ただし、インタフェースなしのビューでは、個別のインタフェースは必要ありません。つまり、Beanクラスのすべてのパブリック・メソッドは、コール元に自動的に公開されます。デフォルトでは、空のimplements
句を持ち、他のローカルまたはリモート・クライアント・ビューを定義しないセッションBeanは、インタフェースなしのクライアント・ビューを公開します。
「インタフェースなしの単純なステートレスEJBの例」には、インタフェースなしのクライアント・ビューのコード・サンプルがあります。また、WebLogic Server配布キットには、インタフェースなしのクライアント・ビューの使用サンプルがバンドルされています。「EJB 3.1: 単純化されたインタフェースなしのプログラミングおよびWARファイルでのパッケージ化」を参照してください。
インタフェースなしのクライアント・ビューの実装の詳細は、Java EE 6チュートリアル(http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html
)の「エンタープライズBean」の章のインタフェースなしのビューを使用したローカル・エンタープライズBeanへのアクセスに関する項を参照してください。
EJB 3.1ビジネス・インタフェースは、EJBのすべてのビジネス・メソッドの完全なシグネチャを記述するプレーンJavaインタフェースです。たとえば、Account
EJBが顧客の当座預金口座を表す場合であれば、そのビジネス・インタフェースには顧客がその口座を管理するためのメソッド(withdraw
、deposit
、balance
など)を含めます。
ビジネス・インタフェースは、他のインタフェースを拡張できます。メッセージドリブンBeanの場合であれば、ビジネス・インタフェースはメッセージ・リスナー・インタフェースにするのが一般的です。どのメッセージング・リスナー・インタフェースにするかは、そのBeanで使用するメッセージングの種類によって決まります。たとえば、JMSの場合はjavax.jms.MessageListener
になります。セッションBeanのインタフェースには、このような明確な種類はありません。ビジネス・ニーズに合わせて、どのようなインタフェースでも使用できます。
注意: EJB 3.1ビジネス・インタフェースの唯一の要件は、EJB 2.xと同様に、 |
ステートレスおよびステートフル・セッションBeanによって実装されたビジネス・インタフェースのサンプルについては、「単純なビジネス・インタフェースを使用するステートレスEJBのサンプル」および「単純なステートフルEJBのサンプル」を参照してください。
ビジネス・インタフェースの指定に関する詳細やサンプルは、第5章「ビジネス・インタフェースとその他のインタフェースを指定する」を参照してください。
EJBのビジネス・メソッドを設計する場合は、EJBのビジネス・インタフェースのメソッドのthrows
句にアプリケーション例外を定義できます。「アプリケーション例外」とは、Beanクラス内に作成したプログラムからクライアントに、アプリケーション・レベルの異常な状態を警告するための例外です。たとえば、顧客が当座預金口座の引出し可能額を超える金額を引き出そうとしたときに、その口座を表すAccount
EJBのwithdraw()
メソッドからアプリケーション例外を送出できます。
アプリケーション例外は、システム例外とは異なります。システム例外は、データベース管理システムが利用できないなど、システム・レベルの例外をクライアントに警告するためにEJBコンテナからスローされる例外です。システム・レベルのエラーが、アプリケーション例外として報告されないようにしてください。
また、インタフェースがリモート・ビジネス・インタフェースである場合や、Beanクラスに@WebService
JWSアノテーションが含まれている場合、およびメソッドに@WebMethod
アノテーションが含まれている場合でも、ビジネス・メソッドがjava.rmi.RemoteException
例外を送出しないようにする必要があります。唯一の例外は、ビジネス・インタフェースがjava.rmi.Remote
を拡張している場合です。EJBコンテナでプロトコル・レベルの問題が発生すると、基底のRemoteException
をラップしたEJBException
が送出されます。
注意:
|
EJB 3.1プログラミング・モデルでは、ビジネス・インタフェースにおいてクラス・レベルでジェネリックスを使用できます。
ジェネリックスを使用する場合のベスト・プラクティスとしては、まずジェネリックスを使用するスーパーインタフェースを定義し、実際のビジネス・インタフェースでは特定のデータ型を使用してこのスーパーインタフェースを拡張することをお薦めします。
次に、この方法のサンプルを示します。まず、ジェネリックスを使用するスーパーインタフェースをプログラミングします。
public interface RootI<T> { public T getObject(); public void updateObject(T object); }
次に、実際のビジネス・インタフェースをプログラミングし、特定のデータ型でRootI<T>
を拡張します。
@Remote public interface StatelessI extends RootI<String> { }
最後に、実際のステートレス・セッションBeanをプログラミングしてビジネス・インタフェースを実装します。メソッドの実装では、指定したデータ型(この場合はString
)を使用します。
@Stateless public class StatelessSample implements StatelessI { public String getObject() { return null; } public void updateObject(String object) { } }
ビジネス・インタフェースまたはクラスで型変数を定義しても削除されます。この場合、ビジネス・インタフェースがBeanクラスによって他のジェネリック情報ではなくその型パラメータの上限値でパラメータ化されている場合のみ、EJBアプリケーションを正常にデプロイすることができます。たとえば、次の例の上限値はObject
です。
public class StatelessSample implements StatelessI<Object> { public Object getObject() { return null; } public void updateObject(Object object) { } }
ビジネス・オブジェクトのシリアライズとデシリアライズは、以下のインタフェースでサポートされます。これらのインタフェースは、すべてのビジネス・オブジェクトで実装されます。
weblogic.ejb.spi.BusinessObject
weblogic.ejb.spi.BusinessHandle
BusinessObject._WL_getBusinessObjectHandle()
メソッドを使用して、ビジネス・ハンドル・オブジェクトを取得し、シリアライズします。
ビジネス・オブジェクトをデシリアライズするには、ビジネス・ハンドル・オブジェクトをデシリアライズし、BusinessHandle.getBusinessObject()
メソッドを使用してビジネス・オブジェクトを取得します。
インターセプタは、ビジネス・メソッドの呼出しやライフサイクル・コールバック・イベントをインターセプトするメソッドです。
インターセプタ・メソッドは、実際のBeanクラス内に定義できますが、Beanクラスとは別にインターセプタ・クラスをプログラミングして@javax.ejb.Interceptor
アノテーションでBeanクラスに関連付けることもできます。
インターセプタを使用するBeanクラスのプログラミングについては、「ビジネス・メソッドまたはライフサイクル・コールバック・イベントのインターセプタを指定する」を参照してください。
WebLogic Serverは、EJB 3.1仕様で定義されているEJBタイマー・サービスをサポートしています。EJBタイマー・サービスは、EJB 3.1仕様のとおり、時間ベースのイベントに対してコールバックをスケジュールできるコンテナ管理によるサービスです。コンテナは、時限イベントに関する信頼性の高いトランザクション通知サービスを提供します。タイマー通知は、カレンダベースのスケジュールに応じて、特定の時刻、特定の経過時間後、または特定の反復間隔で発生するようにスケジュールできます。
タイマー・サービスは、EJBコンテナで実装されます。エンタープライズBeanは、EJBContext
インタフェースを介して、またはJNDIネームスペースのルックアップを介して、依存関係インジェクションによってこのサービスにアクセスします。
タイマー・サービスは、大まかなタイマー・サービスとして使用するように設計されています。大量のタイマー・オブジェクトを使用してデータ・セットに対して同じタスクを実行するより、少数のタイマーを使用して大量のタスクを実行することをお薦めします。たとえば、従業員の経費レポートを表すEJBがあるとします。各経費レポートは、マネージャの承認を受けてから処理されなければなりません。この場合、1つのEJBタイマーを使用してすべての未決の経費レポートを定期的に検査し、担当のマネージャに対して、承認待ちのレポートを決裁するように促す電子メールを送信できます。
タイマー・サービスは、タイマーのプログラムによる作成およびキャンセルのほか、Beanに関連付けられているタイマーの検索のためのメソッドを提供します。タイマーは、Beanクラスまたはデプロイメント記述子のメタデータに基づいて、デプロイメント時にコンテナにより自動的に作成することもできます。タイマー・オブジェクトは、ステートレス・セッションBean、シングルトン・セッションBean、メッセージドリブンBean、および2.1エンティティBean用に作成できます。タイマーは、ステートフル・セッションBeanでは作成できません。
注意: 2.1エンティティBeanでは、カレンダベースのタイマー、自動で作成されるタイマー、および非永続タイマー機能はサポートされません。 |
タイマーは、時限コールバックをスケジューリングするために作成されます。タイマー・サービスを使用するエンタープライズBeanのBeanクラスでは、次のようなタイムアウト・コールバック・メソッドを1つ以上を提供する必要があります。
プログラムによるタイマー - プログラムで作成されたタイマーの場合、このメソッドはTimeout
アノテーションの付いたメソッドになります。Beanでjavax.ejb.TimedObject
インタフェースを実装することもできます。javax.ejb.TimedObject
インタフェースは、単一のメソッド、タイマー・コールバック・メソッドejbTimeout
を備えています。
自動タイマー - 自動で作成されるタイマーの場合、タイムアウト・メソッドは、Schedule
アノテーションの付いたメソッドになります。
2.1エンティティBeanタイマー - 2.1エンティティBean用に作成されるタイマーは、エンティティBeanのIDと関連付けられます。ステートレス・セッションBeanまたはメッセージドリブンBean用に作成されるタイマーのタイムアウト・コールバック・メソッド呼出しは、プールされた状態で任意のBeanインスタンスで呼び出すことができます。
EJB 31。タイマー・サービスでは、カレンダベースのEJBタイマー式をサポートします。このスケジューリング機能では、CRONスタイルのスケジュール定義という形式をとっています。これは、EJBメソッドに配置され、定義されたスケジュールに応じてメソッドを自動的に呼び出せます。
注意: EJB 2.xエンティティBeanでは、カレンダベースのタイマーはサポートされません。 |
カレンダベースのタイマーは、javax.ejb.TimerService
の2つのメソッドを使用してプログラム的に作成できます。これらは、引数としてjavax.ejb.ScheduleExpression
を受け取ります。タイマーを作成する前に、ScheduleExpression
を作成してデータを入力します。自動カレンダベース・タイマーを作成する場合、javax.ejb.Schedule
アノテーション(および対応するejb-jar.xml
要素)には、カレンダベースのタイマー式を構成できる多数の属性が含まれます。
カレンダベースの時間式の7つの属性の詳細は、Enterprise JavaBeans 3.1仕様(JSR-318)(http://jcp.org/en/jsr/summary?id=318
)のカレンダベースのタイマー式に関する第18.2.1項を参照してください。
EJB 3.1タイマー・サービスでは、Beanクラスまたはデプロイメント記述子のメタデータに基づくタイマーの自動作成をサポートします。これによりBean開発者は、Bean呼出しに依存せずにタイマーをスケジューリングし、プログラムでいずれかのTimer Serviceタイマー作成メソッドを呼び出すことができます。自動作成されるタイマーは、アプリケーション・デプロイメントの結果としてコンテナで作成されます。
javax.ejb.Schedule
アノテーションを使用して、特定のタイムアウト・スケジュールを持つタイマーを自動的に作成できます。このアノテーションは、そのスケジュールに関連付けられるタイマー・コールバックを受け取るBeanクラス(またはスーパークラス)のメソッドに適用されます。javax.ejb.Schedules
アノテーションを使用して、複数の自動タイマーを単一のタイムアウト・コールバック・メソッドに適用できます。
クラスタ化EJBタイマー実装を使用する場合、EJBがデプロイされているサーバー数にかかわらず、それぞれのSchedule
アノテーションは単一の永続タイマーに対応します。
デフォルトでは、EJBタイマーは永続します。非永続タイマーは、その存続時間が、タイマーが作成されたJVMに関係するタイマーです。非永続タイマーは、アプリケーションの停止、コンテナのクラッシュ、タイマーが起動されたJVMの失敗/停止のイベントが発生すると、キャンセルと見なされます。
注意: EJB 2.xエンティティBeanでは、非永続タイマーはサポートされません。 |
非永続タイマーは、プログラムで作成することも自動的に作成することもできます(@Schedule
またはデプロイメント記述子を使用します)。
自動の非永続タイマーを指定するには、@Schedule
アノテーションの永続属性をfalseに設定します。自動の非永続タイマーでは、コンテナが配信される各JVMのアプリケーションの初期化時に、コンテナで新しい非永続タイマーを作成します。
EJBタイマー・サービスは、2つのタイプ(クラスタまたはローカル)を構成することができます。
クラスタ化EJBタイマー・サービスには、次の利点があります。
可視性に優れています。
クラスタ内のすべてのノードからタイマーにアクセスできます。たとえば、javax.ejb.TimerService.getTimers()
メソッドを使用すると、EJBに対して作成されたクラスタに含まれるすべてのステートレス・セッションBeanタイマーまたはメッセージドリブンBeanタイマーの完全なリストが返されます。エンティティBeanの主キーをgetTimers()
メソッドに渡すと、そのエンティティBeanのタイマーのリストが返されます。
自動ロード・バランシングおよびフェイルオーバー
クラスタ化EJBタイマー・サービスは、ジョブ・スケジューラのロード・バランシング機能とフェイルオーバー機能を利用できます。
クラスタ化EJBタイマー・サービスの構成については、「クラスタ化EJBタイマーの構成」を参照してください。
ローカルEJBタイマー・サービスは、ローカルEJBタイマー・サービスが作成されたサーバー上でのみ実行され、そのサーバー上のBeanにしか認識されません。ローカルEJBタイマー・サービスを使用する場合、クラスタ化EJBタイマー・サービスとは異なり、クラスタ、データベース、JDBCデータ・ソース、またはリース・サービスを構成する必要はありません。
ローカルEJBタイマー・オブジェクトは、別のサーバーに移行できません。タイマー・オブジェクトは、サーバー全体の一部としてのみ移行できます。EJBタイマーが存在するサーバーが何らかの理由でダウンした場合、サーバーを再起動するか、またはサーバー全体を移行しなければタイマーを実行できません。
注意: クラスタ化された環境では、ローカル・タイマー実装に厳密な制限があるため、ローカル・タイマーを使用しないことをお薦めします。そのかわりに、クラスタ化されたタイマー実装を使用します。クラスタ化された環境でローカル・タイマー実装が使用されるように構成されている場合、デプロイメント時に警告がスローされます。 |
EJBタイマーのクラスタリングを構成するには、次のステップを実行します:
以下について構成したかどうかを確認します。
クラスタ化ドメイン。詳細は、『Oracle WebLogic Serverクラスタの管理』のWebLogicクラスタの設定に関する項を参照してください。
ジョブ・スケジューラの以下の機能。
HAデータベース(Oracle、DB2、Informix、MySQL、Sybase、MSSQLなど)。
config.xml
ファイルの<data-source-for-job-scheduler>
要素を使用してHAデータベースにマップされているJDBCデータ・ソース。
リース・サービス。デフォルトでは、データベース・リースが使用され、config.xml
ファイルの<data-source-for-job-scheduler>
要素によって定義されたJDBCデータ・ソースが使用されます。
ジョブ・スケジューラの構成の詳細は、『Oracle WebLogic Server CommonJアプリケーションの開発』のタイマーおよびワーク・マネージャAPIに関する項を参照してください。
クラスタ化EJBタイマー・サービスを有効にするために、weblogic-ejb-jar.xml
デプロイメント記述子のtimer-implementation
要素をClustered
に設定します。
<timer-implementation>Clustered</timer-implementation>
詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』の「weblogic-ejb-jar.xmlデプロイメント記述子のリファレンス」のtimer-implementation要素の説明を参照してください。
クラスタ化EJBタイマー・サービスでは、以下のように動作が変更されることに注意してください。
weblogic.ejb.WLTimer*
インタフェースは、クラスタ化EJBタイマー・サービスではサポートされません。
createTimer()
メソッドを使用してクラスタ化EJBタイマーを新しく作成する場合、タイマーの初期セット・アップ時にタイムアウトの実行が遅延する場合があります。
ジョブ・スケジューラでは、「少なくとも1回」の実行が保証されます。クラスタ化EJBタイマーが期限切れになった場合、データベースはリスナー・コールバック・メソッドが完了するまで更新されません。データベースが更新される前にサーバーがクラッシュした場合、タイマーはもう一度実行されます。
クラスタ化EJBタイマー・サービスでは、障害が発生した場合に実行するアクションに関するタイマーの構成オプションは使用できません。これらの構成オプションには、再試行の遅延、再試行の最大数、タイムアウトの最大数、およびタイムアウト・エラー・アクションがあります。
ジョブ・スケジューラは、期限切れになるタイマーを識別するために30秒ごとにデータベースに対して問合せを実行します。30秒未満の間隔でタイマーの実行が遅延する場合があります。
障害が発生した場合、トランザクション対応のタイマーのみ再試行されます。
タイマー実行の固定間隔スケジューリングはサポートされません。
この節では、EJB 3.1仕様に定義されている、タイマーのプログラミングに使用できるJavaプログラミング・インタフェースについて説明します。これらのインタフェースの詳細は、EJB 3.1仕様を参照してください。また、この節では、WebLogic Server固有のタイマー関連インタフェースについて詳しく説明します。
次の表に、タイマーのプログラミングに使用できるEJB 3.1インタフェースを示します。
表4-2 EJB 3.1タイマー関連プログラミング・インタフェース
プログラミング・インタフェース | 説明 |
---|---|
|
カレンダベースEJBタイマー式の作成 |
|
特定のタイムアウト・スケジュールを持つタイマーを自動的に作成します。
|
|
タイマー・コールバックのためにタイマー・サービスに登録されるBeanのエンタープライズBeanクラスによって実装されます。このインタフェースは、単一のメソッド、 |
|
|
|
EJBの新しいEJBタイマーを作成するか、既存のEJBタイマーにアクセスします。 |
|
特定のEJBタイマーに関する情報にアクセスします。 |
|
永続化できるシリアライズ可能なタイマー・ハンドルを定義します。タイマーはローカル・オブジェクトなので、 |
EJB 2.1のタイマー関連プログラミング・インタフェースの詳細は、EJB 2.1仕様を参照してください。
タイマーのプログラミングに使用できるWebLogic Server固有のインタフェースは以下のとおりです。
weblogic.management.runtime.EJBTimerRuntimeMBean
。特定のEJBHome
のタイマーの実行時情報と管理機能を提供します。例4-3にweblogic.management.runtime.EJBTimerRuntimeMBean
インタフェースを示します。
例4-3 weblogic.management.runtime.EJBTimerRuntimeMBeanインタフェース
public interface weblogic.management.runtime.EJBTimerRuntimeMBean { public int getTimeoutCount(); // get the number of successful timeout notifications that have been made public int getActiveTimerCount(); // get the number of active timers for this EJBHome public int getCancelledTimerCount(); // get the number of timers that have been cancelled for this EJBHome public int getDisabledTimerCount(); // get the number of timers temporarily disabled for this EJBHome public void activateDisabledTimers(); // activate any temporarily disabled timers }
weblogic.ejb.WLTimerService
インタフェース。javax.ejb.TimerService
インタフェースの拡張です。このインタフェースを使用すると、タイマーに関するWebLogic Server固有の構成情報を指定できます。例4-4にweblogic.ejb.WLTimerService
インタフェースを示します。javax.ejb.TimerService
の詳細は、EJB 2.1仕様を参照してください。
例4-4 weblogic.ejb.WLTimerServiceインタフェース
public interface WLTimerService extends TimerService { public Timer createTimer(Date initial, long duration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(Date expiration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(long initial, long duration, Serializable info WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(long duration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; }
weblogic.ejb.WLTimerInfo
インタフェース。weblogic.ejb.WLTimerService
インタフェースで使用され、タイマーに関するWebLogic Server固有の構成情報を渡します。例4-5にweblogic.ejb.WLTimerInfo
インタフェースを示します。
例4-5 weblogic.ejb.WLTimerInfoインタフェース
public final interface WLTimerInfo { public static int REMOVE_TIMER_ACTION = 1; public static int DISABLE_TIMER_ACTION = 2; public static int SKIP_TIMEOUT_ACTION = 3; /** * Sets the maximum number of retry attempts that will be * performed for this timer. If all retry attempts * are unsuccesful, the timeout failure action will * be executed. */ public void setMaxRetryAttempts(int retries); public int getMaxRetryAttempts(); /** * Sets the number of milliseconds that should elapse * before any retry attempts are made. */ public void setRetryDelay(long millis); public long getRetryDelay(); /** * Sets the maximum number of timeouts that can occur * for this timer. After the specified number of * timeouts have occurred successfully, the timer * will be removed. */ public void setMaxTimeouts(int max); public int getMaxTimeouts(); /** * Sets the action the container will take when ejbTimeout * and all retry attempts fail. The REMOVE_TIMER_ACTION, * DISABLE_TIMER_ACTION, and SKIP_TIMEOUT_ACTION fields * of this interface define the possible values. */ public void setTimeoutFailureAction(int action); public int getTimeoutFailureAction(); }
weblogic.ejb.WLTimer
インタフェース。javax.ejb.Timer
インタフェースの拡張であり、タイマーの現在の状態に関する追加情報を提供します。例4-6にweblogic.ejb.WLTimer
インタフェースを示します。
この項では、エンタープライズBeanへのアクセスを提供するクライアント・ビューを決定する際のガイドラインを示します。
EJB 3.1仕様に示されているように、リモート・クライアントは、Beanのリモート・ビジネス・インタフェースを介してセッションBeanにアクセスします。EJB 2.1以前のAPIに記述されたセッションBeanクライアントおよびコンポーネントでは、リモート・クライアントは、セッションBeanのリモート・ホームおよびリモート・コンポーネント・インタフェースを介してセッションBeanにアクセスします。
注意: EJB 2.1以前のAPIでは、リモート・クライアントが、セッションBeanのリモート・ホームおよびリモート・コンポーネント・インタフェースによって、ステートフルまたはステートレスのセッションBeanにアクセス必要がありました。これらのインタフェースは、EJB 3.xでも使用できます。詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のEJBクラスおよびインタフェースの作成に関する項を参照してください。 |
エンタープライズBeanのリモート・クライアント・ビューは、場所に関係なく動作します。Beanインスタンスと同じJVMで稼働しているクライアントは、同じAPIを使用して、同じマシンまたは別のマシン上の異なるJVMで稼働するクライアントとしてBeanにアクセスします。
EJB 3.1仕様で示されているように、ローカル・クライアントは、Beanのローカル・ビジネス・インタフェース、またはBeanクラスのすべてのパブリック・メソッドを示すインタフェースなしのクライアント・ビューを介してセッションBeanにアクセスします。EJB 2.1以前のAPIに記述されたセッションBeanまたはエンティティBeanクライアントおよびコンポーネントでは、ローカル・クライアントは、Beanのローカル・ホームおよびローカル・コンポーネント・インタフェースを介してエンタープライズBeanにアクセスします。ローカル・ビジネス・インタフェースまたはインタフェースなしのローカル・ビューを実装するコンテナ・オブジェクトは、ローカルJavaオブジェクトです。
ローカル・クライアントは、ローカル・クライアント・ビューを提供するセッションBeanが同じアプリケーション内に存在し、そのBeanと密結合できるクライアントです。セッションBeanのローカル・クライアントは、別のエンタープライズBeanまたはWebコンポーネントにすることもできます。ローカル・クライアント・ビューを介してエンタープライズBeanにアクセスするには、ローカル・クライアント・ビューを提供するエンタープライズBeanとローカル・クライアントが同じアプリケーション内に配置される必要があります。そのため、ローカル・クライアント・ビューでは、リモート・クライアント・ビューに備わる位置の透過性は提供されません。
エンタープライズBeanのクライアントは、エンタープライズBeanのインスタンスへの参照を取得します。そのためには、Javaプログラミング言語のアノテーションで依存関係インジェクションを使用するか、エンタープライズBeanインスタンスを検索するJNDI構文を使用してJNDIルックアップを実行します。
注意: クライアントでEJBリンクを使用して2.x以前のエンタープライズBeanをルックアップする方法の詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のEJBリンクの使用に関する項を参照してください。 |
依存関係インジェクションでは、Beanコンテキスト内のリソースや他の環境エントリへの参照が、EJBコンテナによってBeanの変数またはセッター・メソッドに自動的に提供(注入)されます。依存関係インジェクションは、javax.ejb.EJBContext
インタフェースまたはJNDI APIを使用したリソースのルックアップを、より簡単にプログラミングするための方法にすぎません。
依存関係インジェクションを指定するには、注入するリソースのタイプに応じて、以下のアノテーションのいずれかを変数またはセッター・メソッドに追加します。
@javax.ejb.EJB
- 別のEJBへの依存性を指定します。
@javax.annotation.Resource
- 外部リソース(JDBCデータ・ソース、JMS宛先、接続ファクトリなど)への依存性を指定します。
詳細は、「変数またはセッター・メソッドにリソース依存性を注入する」を参照してください。
EJB 3.1のポータブルなグローバルJNDIネーミング・オプションは、多数の一般的なネームスペースを提供します。ここにEJBコンポーネントを登録し、この節に記載されているパターンを使用して検索できます。これにより、EJBコンポーネントをJNDIに登録する方法および場所、およびそれらをアプリケーションでルックアップおよび使用する方法を標準化します。
ポータブルJNDIルックアップでは、java:global
、java:module
、java:app
という3つのJNDIネームスペースが使用されます。
java:global
JNDIネームスペースは、JNDIルックアップを使用してリモート・エンタープライズBeanを検索するポータブルな方法です。JNDIアドレスは、次のような形式です。
java:global
[/アプリケーション名]/モジュール名/エンタープライズBean名[/インタフェース名
]
アプリケーション名およびモジュール名のデフォルトは、アプリケーションおよびモジュールからファイル拡張子を除いた名前になります。アプリケーション名は、アプリケーションがEAR内にパッケージ化される場合にのみ必要になります。インタフェース名は、エンタープライズBeanが複数のビジネス・インタフェースを実装する場合にのみ必要になります。
java:module
ネームスペースは、同じモジュール内でローカル・エンタープライズBeanをルックアップする際に使用されます。java:module
ネームスペースを使用するJNDIアドレスは、次の形式になります。
java:module
/エンタープライズBean名/[インタフェース名
]
インタフェース名は、エンタープライズBeanが複数のビジネス・インタフェースを実装する場合にのみ必要になります。
java:app
ネームスペースは、同じアプリケーション内でパッケージ化されたローカル・エンタープライズBeanをルックアップする際に使用されます。つまり、エンタープライズBeanは、複数のJava EEモジュールを含むEARファイル内でパッケージ化されます。ava:app
ネームスペースを使用するJNDIアドレスは、次の形式になります。
java:app
[/モジュール名]/エンタープライズBean名[/インタフェース名
]
モジュール名は必要に応じて指定します。インタフェース名は、エンタープライズBeanが複数のビジネス・インタフェースを実装する場合にのみ必要になります。
たとえば、エンタープライズBeanのMyBean
がWebアプリケーション・アーカイブmyApp.war
の中にパッケージ化される場合、デフォルトのモジュール名はmyApp
になります。(この場合、web.xml
ファイルでモジュール名を明示的に構成できます。)ポータブルJNDI名は、java:module/MyBean
です。java:global
ネームスペースを使用して同じJNDI名を表すと、java:global/myApp/MyBean
となります。
グローバルJNDIバインディングはデフォルトで登録されますが、weblogic.javaee.JNDIName
およびweblogic.javaee.JNDINames
アノテーションを使用して、EJBクライアント・ビュー・バインディングのJNDI名をカスタマイズすることもできます。詳細は、「weblogic.javaee.JNDIName」および「weblogic.javaee.JNDINames」を参照してください。
デプロイメント記述子を使用するEJBでは、weblogic-ejb-jar.xml
デプロイメント記述子のjndi-binding
要素を使用して、カスタムのJNDIバインディングを指定できます。詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のEJBデプロイメント記述子に関する項を参照してください。
EJBがjava.net.URL
リソース・マネージャ接続ファクトリ・タイプを使用して外部HTTPサーバーとのHttpURLConnection
を開くようにするには、URLまたはURLに対応するJNDIツリーでバインドされたオブジェクトを、Beanクラスの@Resource
アノテーションを使用するか、またはデプロイメント記述子を使用する場合はejb-jar.xml
のresource-ref
要素およびweblogic-ejb-jar.xml
のres-ref-name
要素を使用して指定します。
EJBのリクエストが送信されるURLをアノテーションを使用して指定するには:
BeanクラスのURLフィールドに@Resource
で注釈付けします。
@Resource
のlook-up要素を使用してURLの値を指定します。
EJBのリクエストが送信されるURLを、デプロイメント記述子を使用して指定するには:
ejb-jar.xml
のresource-ref
要素の<jndi-name>
要素でURLを指定します。
weblogic-ejb-jar.xml
のresource-description
要素の<jndi-name>
要素でURLを指定します。
<resource-description> <res-ref-name>url/MyURL</res-ref-name> <jndi-name>http://www.rediff.com/</jndi-name> </resource-description>
WebLogic Serverは指定されたjndi-name
でURLオブジェクトを作成し、そのオブジェクトをjava:comp/env
にバインドします。
JNDIでバインドされURLに対応するオブジェクトを、URLを指定するかわりにアノテーションを使用して指定するには:
BeanクラスのURLフィールドに@Resource
で注釈付けします。
@Resource
のlook-up要素を使用して、URLがJNDIでバインドされている名前を指定します。
JNDIでバインドされURLに対応するオブジェクトを、URLを指定するかわりにデプロイメント記述子を使用して指定するには:
ejb-jar.xml
のresource-ref
要素の<jndi-name>
要素で、URLがJNDIでバインドされている名前を指定します。
次のように、weblogic-ejb-jar.xml
のresource-description
要素の<jndi-name>
要素で、URLがJNDIでバインドされている名前を指定します。
<resource-description> <res-ref-name>url/MyURL1</res-ref-name> <jndi-name>firstName</jndi-name> </resource-description>
firstName
は、URLに対応するJNDIツリーにバインドされたオブジェクトです。このバインディングは、起動クラスで行うこともできます。jndi-name
が有効なURLでない場合、WebLogic ServerはそれをURLに対応し、すでにJNDIツリーにバインドされているオブジェクトとして取り扱い、LinkRef
とそのjndi-name
をバインドします。
HTTPリソースの指定方法(URLかURLに対応するJNDI名か)に関係なく、次のようにしてEJBのコードからそのHTTPリソースにアクセスできます。
URL url = (URL) context.lookup("java:comp/env/url/MyURL"); connection = (HttpURLConnection)url.openConnection();
以降の節では、トランザクション・プログラミングのガイドラインを示します。
コンテナ管理によるトランザクションは、Bean管理によるトランザクションよりもプログラミングが簡単です。その理由は、境界設定(トランザクションの開始と停止)がEJBコンテナで行われるからです。目的のトランザクション動作を構成するには、EJBアノテーションjavax.ejb.TransactionAttribute
を使用するか、EJBデプロイメント記述子ejb-jar.xml
およびweblogic-ejb-jar.xml
を使用します。
EJBアノテーションを使用して、Beanファイルでコンテナ管理によるトランザクションを指定する方法の詳細は、第5章「トランザクション管理とトランザクション属性を指定する」を参照してください。
EJBデプロイメント記述子を使用して、コンテナ管理によるトランザクションを指定する方法の詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のコンテナ管理によるトランザクション要素に関する項を参照してください。
コンテナ管理によるトランザクションの主なプログラミング・ガイドラインは以下のとおりです。
トランザクション境界の保持 - コンテナが設定したトランザクションの境界に干渉するメソッドは呼び出さないでください。以下のメソッドは使用しないでください。
java.sql.Connection
のcommit
、setAutoCommit
、およびrollback
メソッド
javax.ejb.EJBContext
のgetUserTransaction
メソッド
javax.transaction.UserTransaction
のすべてのメソッド
トランザクションの明示的なロールバック - 明示的にコンテナがコンテナ管理によるトランザクションをロールバックするようにするには、EJBContext
インタフェースのsetRollbackOnly
メソッドを呼び出します。(Beanから非アプリケーション例外(主としてEJBException
)がスローされる場合、ロールバックは自動的に行われます。)
シリアライゼーション問題の回避 - 多くのデータ・ストアでは、シリアライゼーションに関する問題の検出は、単一ユーザー接続の場合でさえ制限されています。そのような場合は、weblogic-ejb-jar.xml
のtransaction-isolation
がTransactionSerializable
に設定されていても、同じ行でクライアント間に競合が発生した場合はEJBクライアントで例外またはロールバックが発生する場合があります。そのような例外を回避するために、以下のことができます。
SQL例外を捕捉して(たとえばトランザクションを再起動などして)適切に解決するコードをクライアント・アプリケーションに含める
Oracleデータベースでは、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』の付録「weblogic-ejb-jar.xmlデプロイメント記述子のリファレンス」の「isolation-level
」で説明されているトランザクション分離設定を使用します。
Oracle WebLogic Serverでは、トランザクションを開始したビジネス・メソッドが、システム例外に関連のないトランザクション・ロールバックが原因で失敗した場合、EJBコンテナが新しいトランザクションを開始し、失敗したメソッドを指定された回数まで再試行するように指定できます。メソッドの失敗が指定された再試行回数に達した場合、EJBコンテナは例外をスローします。
注意: EJBコンテナは、システム例外に基づくエラーが原因で失敗したトランザクションは再試行しません。 |
コンテナ管理によるトランザクションの自動的な再試行を構成するには:
使用するBeanがコンテナ管理によるセッションBeanまたはエンティティBeanであることを確認します。
コンテナ管理によるセッションBeanおよびエンティティBeanの場合にのみ、コンテナ管理によるトランザクションの自動再試行を構成できます。メッセージドリブンBeanの場合は、コンテナ管理によるトランザクションの自動再試行を構成できません。MDBは、メッセージの受信を含むトランザクションがロールバックされたときに、そのメッセージの受信の確認応答を行わないため、メッセージは確認応答が行われるまで自動的に再試行されます。また、タイマーBeanの場合も、コンテナ管理によるトランザクションの自動再試行は構成できません。また、タイマーBeanの場合も、コンテナ管理によるトランザクションの自動再試行は構成できません。タイマーBeanのejbTimeoutメソッドが開始されてロールバックされると、タイムアウトが常に再試行されるからです。
トランザクションの自動再試行を構成する場合、対象となるビジネス・メソッドは、Beanのリモートまたはローカル・インタフェースの内部か、またはホーム・インタフェースのホーム・メソッド(特定のBeanインスタンスに固有ではないローカル・ホーム・ビジネス・ロジック)として定義されている必要があります。メソッドには、以下のコンテナ管理トランザクション属性の1つが設定されていなければなりません。
RequiresNew
。メソッドのトランザクション属性(ejb-jar.xml
のtrans-attribute
要素)がRequiresNew
の場合、メソッドの呼出し前に常に新しいトランザクションが開始され、構成されている場合、そのトランザクションが失敗すると自動再試行が行われます。
Required
。メソッドのトランザクション属性(ejb-jar.xml
のtrans-attribute
要素)がRequired
の場合、メソッドが新しいトランザクションで再試行されるのは、失敗したトランザクションがそのメソッドのために開始された場合のみです。
詳細については、以下を参照してください。
プログラミング・インタフェースについては、「EJBクライアントへのアクセスのプログラミング」を参照してください。
ejb-jar.xml
のtrans-attribute
要素については、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のコンテナ管理によるトランザクション要素に関する項を参照してください。ここには、EJBデプロイメント記述子の作成および編集に関する詳細情報が記載されています。
トランザクションの自動再試行を有効にする場合、対象となるメソッドは再呼出しできなければなりません。失敗したメソッドの再試行によって得られる結果は、直前の再試行が成功した場合に得られる結果と同じでなければなりません。特に、以下の場合です。
メソッドの呼出しによって呼出しチェーンが開始された場合、そのメソッドを再試行するときは呼出しチェーン全体を再呼び出しするのが安全です。
メソッドのすべてのパラメータを再利用できなければなりません。メソッドが再試行される場合、そのメソッドは失敗したメソッドを呼び出すために使用されたパラメータで再試行されます。一般に、再利用できるパラメータは、プリミティブ、不変オブジェクト、または読取り専用オブジェクトの参照です。パラメータがメソッドによって変更されるオブジェクトの参照である場合、メソッドの再呼出しによってメソッド呼出しの結果に悪影響が生じないようにしてください。
再試行されるメソッドを保持するBeanがステートフル・セッションBeanである場合、そのBeanの対話状態は再呼出し時に失われてはなりません。ステートフル・セッションBeanの状態はトランザクション対応ではなく、トランザクションのロールバック中に復元できないので、トランザクションの自動再試行の機能を使用する場合、Beanの状態がロールバック後も有効であることを確認しておく必要があります。
EJBコンテナがどのメソッドのトランザクションを自動的に再試行するか、およびその回数は、weblogic-ejb-jar.xml
のretry-methods-on-rollback
要素で指定します。
retry-methods-on-rollbackのretry-count
下位要素は、管理コンソールからも変更できます。
この節では、Bean管理によるトランザクションのプログラミング上の考慮事項を示します。
トランザクションの境界設定 - EJBまたはクライアント・コードにトランザクション境界を定義するには、Java Transaction Service (JTS)またはJDBCデータベース接続を取得する前に、UserTransaction
オブジェクトを取得してトランザクションを開始しなければなりません。UserTransaction
オブジェクトを取得するには、次のコマンドを使用します。
ctx.lookup("javax.transaction.UserTransaction");
UserTransaction
オブジェクトを取得した後は、tx.begin()
、tx.commit()
、tx.rollback()
でトランザクションの境界を指定します。
データベース接続を取得してからトランザクションを開始した場合、その接続は新しいトランザクションと何の関連性も持たず、以後のトランザクション・コンテキストにその接続を「入れる」ためのセマンティクスも存在しません。JTS接続がトランザクション・コンテキストに関連付けられていない場合、JTS接続はautocommit
をtrue
に設定した標準のJDBC接続と同じように動作し、更新はデータ・ストアに自動的にコミットされます。
いったんトランザクション・コンテキスト内にデータベース接続が作成されると、その接続はトランザクションがコミットまたはロールバックされるまで確保されます。パフォーマンスとスループットを最適化するには、トランザクションを迅速に完了させることによって、データベース接続を解放し、他のクライアント・リクエストが使用できるようにする必要があります。
注意: アクティブなトランザクション・コンテキストには単一のデータベース接続しか関連付けることができません。 |
トランザクション分離レベルの設定 - Bean管理によるトランザクションでは、分離レベルはBeanコードで定義します。有効な分離レベルは、java.sql.Connection
インタフェースで定義されます。分離レベルの動作の詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』の付録「weblogic-ejb-jar.xmlデプロイメント記述子のリファレンス」の「isolation-level
」を参照してください。
サンプル・コードについては、例4-7を参照してください。
例4-7 BMTでのトランザクション分離レベルの設定
import javax.transaction.Transaction; import java.sql.Connection import weblogic.transaction.TxHelper: import weblogic.transaction.Transaction; import weblogic.transaction.TxConstants; User Transaction tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction"); //Begin user transaction tx.begin(); //Set transaction isolation level to TransactionReadCommitted Transaction tx = TxHelper.getTransaction(); tx.setProperty (TxConstants.ISOLATION_LEVEL, new Integer (Connection.TransactionReadCommitted)); //perform transaction work tx.commit();
制限されたメソッドの回避 - Bean管理によるトランザクションでは、EJBContext
インタフェースのgetRollbackOnly
メソッドとsetRollbackOnly
メソッドは呼び出さないでください。これらのメソッドは、コンテナ管理によるトランザクションのみで使用します。Bean管理によるトランザクションでは、UserTransaction
インタフェースのgetStatus
メソッドとrollbackメソッドを呼び出します。
アクティブなトランザクション・コンテキストにつき1つの接続の使用 - アクティブなトランザクション・コンテキストに関連付けることができるのは、1つのデータベース接続だけです。
この節では、複数のBean(複数のサーバー・インスタンスに存在する場合もある)にトランザクションを分散させる2つのアプローチを説明します。
次の断片的なコードは、UserTransaction
オブジェクトを取得し、それを使用してトランザクションを開始およびコミットするクライアント・アプリケーションから引用したものです。クライアントは、トランザクションのコンテキストの中で2つのEJBを呼び出します。
import javax.transaction.*;
...
u = (UserTransaction) jndiContext.lookup("javax.transaction.UserTransaction");
u.begin();
account1.withdraw(100);
account2.deposit(100);
u.commit();
...
account1
とaccount2
のBeanで実行される更新は、1つのUserTransaction
のコンテキスト内で行われます。同じサーバー・インスタンス上にあるか、異なるサーバー・インスタンスにあるか、またはWebLogic Serverクラスタにあるのかに関係なく、EJBは1つの論理単位として一緒にコミットまたはロールバックされます。
1つのトランザクション・コンテキストから呼び出されるEJBはすべて、クライアント・トランザクションをサポートしている必要があります。つまり、ejb-jar.xml
の各Beanのtrans-attribute
要素が、Required
、Supports
、またはMandatory
に設定されている必要があります。
トランザクションをカプセル化する「ラッパー」EJBを使用できます。クライアントはラッパーEJBを呼び出して銀行振替などのアクションを実行し、ラッパーは新しいトランザクションを開始して、トランザクションの処理を実行する1つまたは複数のEJBを呼び出します。
ラッパーEJBは、他のEJBを呼び出す前にトランザクション・コンテキストを明示的に取得できます。あるいは、ejb-jar.xml
でラッパーのtrans-attribute
要素がRequired
またはRequiresNew
に設定されている場合、WebLogic Serverは新しいトランザクション・コンテキストを自動的に作成できます。
ラッパーEJBによって呼び出されるすべてのEJBは、そのラッパーEJBのトランザクション・コンテキストをサポートしている必要があります。つまり、そのtrans-attribute
要素がRequired
、Supports
、またはMandatory
に設定されていなければなりません。
EJB BeanクラスのJavaソース・コードの記述と、必要に応じてインターセプタ・クラスの記述が完了したら、それらをクラス・ファイルにコンパイルする必要があります(通常は標準Javaコンパイラを使用します)。生成されたクラス・ファイルは、デプロイメント用のターゲット・モジュールにパッケージ化できます。コンパイルするためのツールとしては以下が一般的です。
javac
- Java SE SDKに付属のjavac
コンパイラは、Javaコンパイル機能を提供します。http://www.oracle.com/technetwork/java/javase/documentation/index.html
を参照してください。
weblogic.appc
: デプロイメント時間を短縮するために、weblogic.appc
Javaクラス(またはこれと同等のAntタスクwlappc
)を使用して、デプロイ可能なアーカイブ・ファイル(WAR、JARまたはEAR)をプリコンパイルします。weblogic.appc
でプリコンパイルをすると、特定のヘルパー・クラスが生成され、アプリケーションが現在のJava EE仕様に準拠しているかどうかを確認するための妥当性チェックが実行されます。詳細は、『Oracle WebLogic Serverアプリケーションの開発』のwlappcを使用したモジュールとアプリケーションのビルドに関する項を参照してください。
wlcompile
Antタスク: javac
コンパイラを呼び出して、アプリケーションのJavaコンポーネントを分割開発ディレクトリ構造にコンパイルします。詳細は、『Oracle WebLogic Serverアプリケーションの開発』のwlcompileを使用したアプリケーションのコンパイルに関する項を参照してください。
EJB 3.xプログラミング・モデルの重要な点は、メタデータ・アノテーションが導入されたことです。アノテーションを使用すると、コンテナ内でのBeanの動作、依存関係インジェクションの要求方法などをJavaクラス自体の中で指定でき、EJBの開発プロセスを簡略化できます。アノテーションは、EJBの2.x以前のバージョンで必要だったデプロイメント記述子にかわるものです。
しかしながら、デプロイメント記述子は、EJB 3.xで完全にサポートされます。ただし、Java EE 6標準のデプロイメント記述子は必須ではありません。たとえば、従来の2.xプログラミング・モデルを使用する場合や、後々の開発やデプロイメントの段階でより細かくカスタマイズできるようにする場合、メタデータ・アノテーションに加えて(またはメタデータ・アノテーションのかわりに)標準のデプロイメント記述子を作成できます。
デプロイメント記述子要素は、対応するアノテーションを常にオーバーライドします。たとえば、Beanクラス内に@javax.ejb.TransactionManagement(BEAN)
アノテーションを指定した上で、そのEJB用のejb-jar.xml
デプロイメント記述子を作成し、<transaction-type>
要素をcontainer
に設定した場合は、デプロイメント記述子の値が優先され、このEJBではコンテナ管理によるトランザクションの境界設定が使用されます。
注意: EJB 3.1バージョンでは、2.xでサポートされていたWebLogic固有のEJB機能がすべてサポートされます。ただし、 |
『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』の2.xバージョンでは、Java EE標準およびWebLogic固有のEJBデプロイメント記述子の作成と編集について詳しく説明しています。特に、以下の節を参照してください。
「EJBデプロイメント記述子」(EJBデプロイメント記述子の概要)
「デプロイメント記述子を編集する」
「デプロイメント記述子スキーマおよび文書型定義リファレンス」
「weblogic-ejb-jar.xmlデプロイメント記述子のリファレンス」
「weblogic-cmp-jar.xmlデプロイメント記述子のリファレンス」
エンタープライズ・アプリケーションの一部としてEJBをパッケージ化することをお薦めします。詳細は、『Oracle WebLogic Serverアプリケーションの開発』の分割開発ディレクトリからのデプロイとパッケージ化に関する項を参照してください。
ただし、EJB 3.1ではEJBコンポーネントを直接Webアプリケーション・アーカイブ(WAR)ファイルの中に配置する機能を提供することでパッケージ化が単純化されたため、WebコンポーネントとEJBコンポーネントを格納するアーカイブを個々に作成して、それらをエンタープライズ・アーカイブ(EAR)ファイルで結合する必要がなくなりました。
WebLogic Serverでは、別のアプリケーションのプログラムに基づくクライアントがEJBへのアクセスに必要とするEJBクラスをパッケージ化するためのejb-client.jar
ファイルの使用がサポートされています。
Beanのejb-jar.xml
ファイルのejb-client-jar
要素でクライアントJARの名前を指定します。appc
コンパイラを実行すると、EJBにアクセスするために必要なクラスを持つJARファイルが生成されます。
クライアントJARをリモート・クライアントからアクセスできるようにします。Webアプリケーションの場合は、ejb-client.jar
を/lib
ディレクトリに配置します。非Webクライアントの場合は、クライアントのクラスパスでejb-client.jar
を指定します。
注意: WebLogic Serverのクラスローディング動作は、クライアントがスタンドアロンかどうかによって異なります。 |
EJB 3.1では、エンタープライズBeanクラスをejb-jar
ファイルの中にパッケージ化しなければならないという制限が取り除かれました。そのため、Webアプリケーション・クラスに適用される同じパッケージ化のガイドラインを使用して、EJBクラスをWebアプリケーション・アーカイブ(WAR)の中に直接パッケージ化できます。単にEJBクラスをWEB-INF/classes
ディレクトリかWEB-INF/lib
ディレクトリ内のJARファイルに入れるのみです。必要に応じて、EJBデプロイメント記述子も使用する場合は、それをWEB-INF/ejb-jar.xml
としてパッケージ化できます。appc
コンパイラを実行すると、EJBコンポーネントにアクセスするために必要なクラスを持つWARファイルが生成されます。
WARファイルには、モジュールで定義されたすべてのコンポーネント(Web、エンタープライズBeanなど)間で共有される単一のコンポーネント・ネーミング環境があります。WARファイルで定義されたそれぞれのエンタープライズBeanは、この単一のコンポーネント環境ネームスペースを、WARファイルで定義されたその他すべてのエンタープライズBean、およびWARファイルで定義されたその他すべてのWebコンポーネントと共有します。
WARファイルにパッケージ化されたエンタープライズBean(および関連する任意のクラス)には、WARファイルにパッケージ化された他の非エンタープライズBeanクラスと同じクラス・ローディング要件があります。たとえば、WARファイルの中にパッケージ化されているサーブレットは、同じWARファイルの中にパッケージ化されているエンタープライズBeanコンポーネントを参照できることが保証され、逆もまた保証されます。
注意: EJB 2.1エンティティBeanおよびEJB 1.1エンティティBeanは、WARファイル内ではサポートされません。これらのコンポーネント・タイプは、スタンドアロンの |
WebLogic Server配布キットにバンドルされている、単純化されたWARのパッケージ化メソッドを使用するサンプルがあります。「EJB 3.1: 単純化されたインタフェースなしのプログラミングおよびWARファイルでのパッケージ化」を参照してください。
EJBをデプロイすると、WebLogic ServerはEJBのコンポーネントをクライアントに提供できるようになります。EJBは、ユーザーの環境とEJBが本番環境に置かれるかどうかに基づいて、複数の手順のうちの1つでデプロイできます。
WebLogic Serverアプリケーションおよびモジュール(EJBを含む)をデプロイする一般的な手順については、『Oracle WebLogic Serverへのアプリケーションのデプロイ』を参照してください。EJB固有のデプロイメントの問題および手順の詳細は、「エンタープライズ・アプリケーションの一部としてのスタンドアロンEJBのデプロイメント」および「Webアプリケーションの一部としてのEJBのデプロイメント」を参照してください。
2.xプログラミング・モデルで作成されたEJBのデプロイメントの詳細は、2.xプログラミング・モデルに特化した『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のEnterprise JavaBeansのデプロイメント・ガイドラインに関する項を参照してください。