この章では、WebLogic Serverリソース・アダプタを実装するためのプログラミング・タスクについて説明します。Java EEコネクタ・アーキテクチャで必要なJavaクラスを示します。起動クラスとして実行するリソース・アダプタのプログラミング方法、リソース・アダプタの一時停止と再開の方法、さらにExtendedBootstrapContext
クラスについて説明します。
この章の内容は以下のとおりです。
コネクタ・アーキテクチャ1.6に準拠するリソース・アダプタでは次のJavaクラスが必要です。
ManagedConnectionFactory
ConnectionFactory
インタフェース
ConnectionFactory
実装
Connection
インタフェース
Connection
実装
これらのクラスをra.xml
ファイルに指定します。例:
<managedconnectionfactory-class> com.sun.connector.blackbox.LocalTxManagedConnectionFactory </managedconnectionfactory-class> <connectionfactory-interface> javax.sql.DataSource </connectionfactory-interface> <connectionfactory-impl-class> com.sun.connector.blackbox.JdbcDataSource </connectionfactory-impl-class> <connection-interface> java.sql.Connection </connection-interface> <connection-impl-class> com.sun.connector.blackbox.JdbcConnection </connection-impl-class>
また、リソース・アダプタでインバウンド・メッセージングをサポートする場合は、サポートするインバウンド・メッセージのタイプごとにActivationSpec
クラスが必要になります。第8章「メッセージ・インフローとトランザクション・インフロー」を参照してください。
これらのリソース・アダプタ・クラスの詳細は、開発するリソース・アダプタの性質によって異なります。
コネクタ・アーキテクチャ1.6では汎用ワーク・コンテキストが定義されます。これは、リソース・アダプタが、メッセージの配信またはWorkインスタンスの発行の際に、コンテキスト情報をEISからWebLogic Serverに伝播するために使用するメカニズムです。汎用ワーク・コンテキストは、一連のクラス、インタフェースおよびメソッドで構成されます。また、WebLogic Serverでサポートされる新しいスキーマ要素を含みます。
以下の項では、汎用ワーク・コンテキストをサポートするために追加されたこれらのエンティティについて説明します。
汎用ワーク・コンテキストをサポートするために以下のインタフェースが追加されています。
インタフェース | 説明 |
---|---|
javax.resource.spi.work.WorkContext |
リソース・アダプタがEISからインポートしたコンテキストをアプリケーション・サーバーに伝播するための、標準メカニズムとして使用されます。 |
javax.resource.spi.work.WorkContextLifecycleListener |
|
javax.resource.spi.work.WorkContextProvider |
|
汎用ワーク・コンテキストをサポートするために以下のクラスが追加されています。
クラス | 説明 |
---|---|
javax.resource.spi.work.WorkContextErrorCodes |
|
汎用ワーク・コンテキストをサポートするために以下のメソッドがBootstrapContext
インタフェースに追加されています。
メソッド | 説明 |
---|---|
isContextSupported |
リソース・アダプタは、このメソッドを使用して特定の |
汎用ワーク・コンテキストをサポートするために、required-work-context
要素がra.xml
ファイル・スキーマに追加されています。この要素は、WebLogic Serverがサポートするリソース・アダプタで必要なWorkContext
クラスを表します。必要なWorkContext
クラスごとに個別のrequired-work-context
要素が指定されます。
このデプロイメント記述子情報を指定するために@Connector
メタデータ注釈をリソース・アダプタのソース・ファイルで使用できることに注意してください。詳細は、『JSR 322: Java EE Connector Architecture 1.6』の18.4項「@Connector」を参照してください。
次の項では、起動クラスとして実行するためのリソース・アダプタのプログラミングについて説明します。
WebLogic Server起動クラスを使用する代わりに、javax.resource.ResourceAdapter
を実装した最小限のリソース・アダプタ・クラスを持つリソース・アダプタをプログラミングし、そのクラスでstart()
およびstop()
メソッドを定義することができます。
注意: ResourceAdapterインタフェースの定義のために、 |
リソース・アダプタがデプロイされるときに、start()
メソッドが呼び出されます。アンデプロイされるときに、stop()
メソッドが呼び出されます。WebLogic Server起動クラスと同様に、リソース・アダプタが開始する作業はstart()
メソッドの中で実行できます。
例4-1は、最小限のリソース・アダプタ・クラスを持つリソース・アダプタを示しています。これは、(println
文を除けば)開発できる最小限のリソース・アダプタです。この例では、start()
メソッドで実行される作業はstdout
(標準出力)へのメッセージの出力のみです。
例4-1 最小限のリソース・アダプタ
import javax.resource.spi.ResourceAdapter; import javax.resource.spi.endpoint.MessageEndpointFactory; import javax.resource.spi.ActivationSpec; import javax.resource.ResourceException; import javax.transaction.xa.XAResource; import javax.resource.NotSupportedException; import javax.resource.spi.BootstrapContext; /** * This resource adapter is the absolute minimal resource adapter that anyone can build (other than removing the println's.) */ public class ResourceAdapterImpl implements ResourceAdapter { public void start( BootstrapContext bsCtx ) { System.out.println( "ResourceAdapterImpl started" ); } public void stop() { System.out.println( "ResourceAdapterImpl stopped" ); } public void endpointActivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec) throws ResourceException { throw new NotSupportedException(); } public void endpointDeactivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec) { } public XAResource[] getXAResources(ActivationSpec aactivationspec[]) throws ResourceException { throw new NotSupportedException(); } }
リソース・アダプタでは、start()
メソッド内でBootstrapContext
を介してワーク・マネージャにアクセスするため、直接的なスレッド管理は使用しないで、Work
インスタンスを送信する必要があります。それによって、WebLogic Serverは自動チューニングのワーク・マネージャを通じて、スレッドを効率的に管理できます。
実行用にWorkインスタンスが送信されたら、リソース・アダプタの完全なデプロイメントに干渉しないように、start()
メソッドはすぐに復帰する必要があります。そのため、ワーク・マネージャでは、doWork()
メソッドではなく、scheduleWork()
またはstartWork()
メソッドを呼び出す必要があります。
例4-2は、Workインスタンスをワーク・マネージャに送信するリソース・アダプタを示しています。リソース・アダプタはstart()
メソッド内で作業を開始します。したがって、Java EEに準拠した起動クラスとして機能します。
例4-2 ワーク・マネージャを使用し、Workインスタンスを送信するリソース・アダプタ
import javax.resource.NotSupportedException; import javax.resource.ResourceException; import javax.resource.spi.ActivationSpec; import javax.resource.spi.BootstrapContext; import javax.resource.spi.ResourceAdapter; import javax.resource.spi.endpoint.MessageEndpointFactory; import javax.resource.spi.work.Work; import javax.resource.spi.work.WorkException; import javax.resource.spi.work.WorkManager; import javax.transaction.xa.XAResource; /** * This Resource Adapter starts some work in the start() method, * thus serving as a Java EE compliant "startup class" */ public class ResourceAdapterWorker implements ResourceAdapter { private WorkManager wm; private MyWork someWork; public void start( BootstrapContext bsCtx ) { System.out.println( "ResourceAdapterWorker started" ); wm = bsCtx.getWorkManager(); try { someWork = new MyWork(); wm.startWork( someWork ); } catch (WorkException ex) { System.err.println( "Unable to start work: " + ex ); } } public void stop() { // stop work that was started in the start() method someWork.release(); System.out.println( "ResourceAdapterImpl stopped" ); } public void endpointActivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec) throws ResourceException { throw new NotSupportedException(); } public void endpointDeactivation(MessageEndpointFactory messageendpointfactory, ActivationSpec activationspec) { } public XAResource[] getXAResources(ActivationSpec activationspec[]) throws ResourceException { throw new NotSupportedException(); } // Work class private class MyWork implements Work { private boolean isRunning; public void run() { isRunning = true; while (isRunning) { // do a unit of work (e.g. listen on a socket, wait for an inbound msg, // check the status of something) System.out.println( "Doing some work" ); // perhaps wait some amount of time or for some event try { Thread.sleep( 60000 ); // wait a minute } catch (InterruptedException ex) {} } } public void release() { // signal the run() loop to stop isRunning = false; } } }
リソース・アダプタによるWork
インスタンスの送信が、一過性の失敗を経験するような場合があります。たとえば、『JSR 322: Java EE Connector Architecture 1.6』には、オプションのstartTimeout
パラメータをWorkManagerインタフェース実装で使用して、Workインスタンスの実行を開始する時間間隔を指定する方法が記述されています。Work送信がタイムアウトすると、Work送信エラーが発生し、WorkRejectedExceptionが生成されます。
『JSR 322: Java EE Connector Architecture 1.6』によれば、アプリケーション・サーバーがRetryableWorkRejectedExceptionをスローするのは、Work
送信の失敗の原因が一過性であると判断された場合です。RetryableWorkRejectedExceptionを受け取ると、リソース・アダプタはWork
インスタンスの送信を再試行する場合があります。WebLogic Serverでは、次のような一過性の失敗の状況でRetryableWorkRejectedExceptionがサポートされます。
Work
インスタンスが一時停止中のワーク・マネージャに送信されたとき。
Work
送信がタイムアウトしたとき。
注意: WebLogic Serverでは、接続インスタンスが一時停止中の接続プールに接続しようとすると、再試行可能な例外サポートがアウトバウンド接続プールまで拡張されます。詳細は、「接続の再試行」を参照してください。 |
suspend()
メソッドを使用するようにリソース・アダプタをプログラミングすると、アクティビティを中断するためのカスタムの動作を行えます。たとえば、suspend()
メソッドを使用すると、進行中のトランザクションが完了するまでの間、すべての着信メッセージをキューに入れたり、メッセージの受信が一時的にブロックされていることをエンタープライズ情報システム(EIS)に通知したりできます。
その後でresume()
メソッドを呼び出して、インバウンド・キューを排出してメッセージを配信するように指示したり、EISにメッセージのインバウンドが再び可能になったことを通知したりします。基本的に、resume()
メソッドによってリソース・アダプタは通常の処理を続行できるようになります。
suspend()
およびresume()
メソッドを開始するには、WebLogic Scripting Toolを使用して、またはWebLogic Server管理コンソールから、リソース・アダプタのランタイムMBeanをプログラム的に呼び出します。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのリソース・アダプタの起動と停止に関する項を参照してください。
Suspendable.supportsSuspend()
メソッドでは、リソース・アダプタが特定の種類の中断をサポートしているかどうかを判断します。Suspendable.isSuspended()
メソッドでは、リソース・アダプタが現在中断されているかどうかを判断します。
suspend()
、resume()
、または本番再デプロイメントをサポートするリソース・アダプタでは、Suspendable
インタフェースを実装して、これらの操作がサポートされることをWebLogic Serverに知らせる必要があります。これらの操作は、以下のことが行われた場合にWebLogic Serverによって呼び出されます。
コネクタ・コンポーネントMBeanのsuspend()
メソッドによって中断が呼び出された場合。
(リソース・アダプタを含むアプリケーションの新しいバージョンがデプロイされるときに)本番再デプロイメント・シーケンスが呼び出された場合。「Suspendableインタフェースと本番再デプロイメント」を参照してください。
例4-3では、リソース・アダプタのSuspendable
インタフェースを示しています。
例4-3 Suspendableインタフェース
package weblogic.connector.extensions; import java.util.Properties; import javax.resource.ResourceException; import javax.resource.spi.ResourceAdapter; /** * Suspendable may be implemented by a ResourceAdapter JavaBean if it * supports suspend, resume or side-by-side versioning * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved. * @since November 14, 2003 */ public interface Suspendable { /** * Used to indicate that inbound communication is to be suspended/resumed */ int INBOUND = 1; /** * Used to indicate that outbound communication is to be suspended/resumed */ int OUTBOUND = 2; /** * Used to indicate that submission of Work is to be suspended/resumed */ int WORK = 4; /** * Used to indicate that INBOUND, OUTBOUND & WORK are to be suspended/resumed */ int ALL = 7; /** * May be used to indicate a suspend() operation */ int SUSPEND = 1; /** * May be used to indicate a resume() operation */ int RESUME = 2; /** * Request to suspend the activity specified. The properties may be null or * specified according to RA-specific needs * @param type An int from 1 to 7 specifying the type of suspension being * requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of one * or more of these, or the value Suspendable.ALL ) * @param props Optional Properties (or null) to be used for ResourceAdapter * specific purposes * @exception ResourceException If the resource adapter can't complete the * request */ void suspend( int type, Properties props ) throws ResourceException; /** * Request to resume the activity specified. The Properties may be null or * specified according to RA-specific needs * * @param type An int from 1 to 7 specifying the type of resume being * requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of * one or more of these, or the value Suspendable.ALL ) * @param props Optional Properties (or null) to be used for ResourceAdapter * specific purposes * @exception ResourceException If the resource adapter can't complete the * request */ void resume( int type, Properties props ) throws ResourceException; /** * * @param type An int from 1 to 7 specifying the type of suspend this inquiry * is about (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of * one or more of these, or the value Suspendable.ALL ) * @return true iff the specified type of suspend is supported */ boolean supportsSuspend( int type ); /** * * Used to determine whether the specified type of activity is * currently suspended. * * @param type An int from 1 to 7 specifying the type of activity * requested (i.e. Suspendable.INBOUND, .OUTBOUND, .WORK or the sum of * one or more of these, or the value Suspendable.ALL ) * @return true iff the specified type of activity is suspened by this * resource adapter */ boolean isSuspended( int type ); /** * Used to determine if this resource adapter supports the init() method used for * resource adapter versioning (side-by-side deployment) * * @return true iff this resource adapter supports the init() method */ boolean supportsInit(); /** * Used to determine if this resource adapter supports the startVersioning() * method used for * resource adapter versioning (side-by-side deployment) * * @return true iff this resource adapter supports the startVersioning() method */ boolean supportsVersioning(); /** * Used by WLS to indicate to the current version of this resource adapter that * a new version of the resource adapter is being deployed. This method can * be used by the old RA to communicate with the new RA and migrate services * from the old to the new. * After being called, the ResourceAdapter is responsible for notifying the * Connector container via the ExtendedBootstrapContext.complete() method, that * it is safe to be undeployed. * * @param ra The new ResourceAdapter JavaBean * @param props Properties associated with the versioning * when it can be undeployed * @exception ResourceException If something goes wrong */ void startVersioning( ResourceAdapter ra, Properties props ) throws ResourceException; /** * Used by WLS to inform a ResourceAdapter that it is a new version of an already * deployed resource adapter. This method is called prior to start() so that * the new resource adapter may coordinate its startup with the resource adapter * it is replacing. * @param ra The old version of the resource adapter that is currently running * @param props Properties associated with the versioning operation * @exception ResourceException If the init() fails. */ void init( ResourceAdapter ra, Properties props ) throws ResourceException; }
リソース・アダプタをデプロイするときに、そのアダプタのra.xml
記述子のresource-adapter-class
要素でリソース・アダプタJavaBeanが指定されている場合、Weblogic Serverコネクタ・コンテナでは、『JSR 322: Java EE Connector Architecture 1.6』に従って、そのリソース・アダプタBeanのstart()
メソッドを呼び出します。リソース・アダプタのコードでは、start()
メソッドによって渡されるBootstrapContext
オブジェクトを、次のような目的に使用できます。
Work
インスタンスを送信するためにWorkManager
オブジェクトを取得する
Timer
を作成する
トランザクション・インフローで使用するためのXATerminator
を取得する
このような機能はすべてコネクタ・アーキテクチャ1.6に規定されています。
必須のjavax.resource.spi.BootstrapContext
の実装に加えて、リソース・アダプタのstart()
メソッドに渡されるBootstrapContext
オブジェクトでは、weblogic.connector.extensions.ExtendedBootstrapContext
も実装します。それによって、診断機能を提供し、Contexts and Dependency Injection (CDI)もサポートするWebLogic Server固有の拡張機能に、リソース・アダプタがアクセスできます。以下の節ではこれらの拡張機能について説明します。
WebLogic Server診断フレームワークでは、スレッドに診断コンテキストを関連付けることができます。スレッド上のリクエストは、実行パスに従って進行するように、その診断コンテキストを存続期間中に伝達し続けます。ExtendedBootstrapContext
によって、リソース・アダプタ開発者は、EISからメッセージのエンドポイントに至るリクエストの実行のトレースなどに使用できるStringから構成される診断コンテキストのペイロードを設定できるようになります。
この容量によって、様々な診断プロセスが提供されます。たとえば、EISからのインバウンド・メッセージ上でクライアントIDまたはセッションIDにStringを設定できます。メッセージのディスパッチ中、各種診断が収集されてシステムからリクエスト・フローが表示されます。リソース・アダプタ・クラスの開発時に、setDiagnosticContextID()
およびgetDiagnosticContextID()
メソッドをこの目的で利用できます。
次の診断コンテキスト・ペイロードのコンテンツに関してご注意ください。
ペイロードは、同一の実行コンテキストの他のコードによって表示でき、またWork
インスタンスに従ってプロセスからフローできます。このため、たとえばgetDiagnosticContextID()
メソッドによって返される可能性があるペイロードには、アプリケーションが一切の機密データを含めていないことを確認する必要があります。
ペイロードは同一の実行コンテキストで他のコードによって上書きできます。このため、アプリケーションには、ペイロードで使用可能な固有のコンテキストIDへの依存性は含めません。また、アプリケーションはペイロードのコンテキストIDが使用前に期待される値に一致することを検証する必要もあります。
診断コンテキストの詳細は、『Oracle WebLogic Server診断フレームワークの構成と使用』を参照してください。
WebLogic Server診断フレームワークは、リクエストを仕分けする機能も備えています。ExtendedBootstrapContext
を使用すると、リソース・アダプタ開発者がどの目的で診断を行う場合でも、現在のスレッド上で4つの仕分けビットを設定し、取得できます。たとえば、仕分けビットを使用してリクエストの優先度を設定できます。リクエスト仕分けの詳細は、『Oracle WebLogic Server診断フレームワークの構成と使用』を参照してください。
ExtendedBootstrapContext
.complete()
メソッドをコネクタ・コンテナへのコールバックとして使用できます。この機能の詳細は、『Oracle WebLogic Serverへのアプリケーションのデプロイ』の本番環境でのアプリケーションの再デプロイに関する項を参照してください。
『JSR 303: Bean Validation』をサポートするため、WebLogic ServerはモジュールレベルのBean検証構成ファイルを提供してJava EE 6を拡張します。WebLogic Serverはこれを使用してリソース・アダプタ・モジュールを検証します。
場合によっては、リソース・アダプタによって管理される他のBeanインスタンスの検証を、リソース・アダプタで実行する必要があります。リソース・アダプタには独自のJNDIネームスペースがないため、JNDIを使用して独自のValidator
インスタンスとValidatorFactory
インスタンスをルックアップできません。かわりに、リソース・アダプタはCDIを使用してこれらのBeanをインジェクトできます。または、ExtendedBootstrapContext
インタフェースで次のメソッドを使用して、それらのBeanのインスタンスを取得できます。
getValidator()
getValidatorFactory()
『JSR 299: Contexts and Dependency Injection for the Java EE Platform』(CDI)をサポートするために、WebLogic ServerはExtendedBootstrapContext
インタフェースにgetBeanManager
メソッドを実装します。リソース・アダプタはこのメソッドを呼び出して、独自のBeanManager
インスタンスを取得し、リソース・アダプタ内で管理対象BeanのCDI形式のインジェクションを実行できます。
注意: 以下の制限に注意してください。
|
CDIを使用するためのExtendedBootstrapContext
インタフェースでのgetBeanManager
メソッドの使用の詳細は、第5章「リソース・アダプタでのContexts and Dependency Injectionの使用」を参照してください。
コネクタ・アーキテクチャ1.6によってリソース・アダプタでは、同じインタフェースを実装する複数の管理対象オブジェクト・クラスを持つことができます。ただし、同じインタフェースおよびクラス名の組合せの管理対象オブジェクト定義が多くとも1つ必要です(『JSR 322: Java EE Connector Architecture 1.6』の20.4.1項「Resource Adapter Provider」を参照)。adminobject-type-uniqueness
制約がadminobject-interface
およびadminobject-class
の組合せを定義するために、ra.xml
ファイルのスキーマ定義に追加されています。
以前のリリースのWebLogic Serverでは、weblogic-ra.xml
で定義された管理オブジェクト・グループの、ra.xml
で定義された対応する管理オブジェクトへのマッピングは、管理オブジェクト・インタフェースのみに基づいていました。ただし、同じインタフェースを持つ複数の管理オブジェクト・クラスをサポートするため、WebLogic Serverにはweblogic-ra.xml
のadmin-object-group
要素に対するオプションのadmin-object-class
サブ要素が含まれています。admin-object-class
サブ要素を使用して、管理オブジェクトのインタフェースおよびクラスの組合せを定義できます。WebLogic Serverではこれをra.xml
で定義された対応する管理オブジェクトへマッピングできます。
管理オブジェクト・グループをマッピングする際、WebLogic Serverでは次のルールが使用され、これによっても1.0および1.5のアダプタとの下位互換性が保証されます。
weblogic-ra.xml
で定義された管理オブジェクト・グループに管理オブジェクト・インタフェースおよびクラスの両方が含まれる場合、WebLogic Serverはそのインタフェースおよびクラスを、ra.xml
内の対応する管理オブジェクト定義に照合しようとします。
weblogic-ra.xml
で定義された管理オブジェクト・グループに管理オブジェクト・インタフェースが1つだけ含まれ、照合する管理オブジェクト・インタフェースがra.xml
で複数定義されている場合、WebLogic Serverではエラーが発生します。
weblogic-ra.xml
で定義された管理オブジェクト・グループに管理オブジェクト・インタフェースが1つだけ含まれ、照合する管理オブジェクト・インタフェースがra.xml
で1つだけ定義されている場合、その特定の管理オブジェクト・インタフェースが使用されます。