12 EJBジョブの作成と使用

この章では、Oracle Enterprise Schedulerを使用してEnterprise Java Bean (EJB)ジョブを作成する方法について説明します。

この章の構成は、次のとおりです。

12.1 EJBジョブの作成の概要

EJBジョブ・タイプを使用するとJavaベースのジョブを作成でき、事前デプロイ済のホスティング・アプリケーションの利便性を利用できます。さらに、EJBは別のサーバー上にリモートで配置できます。

Java SEベースのジョブと異なり、EJBジョブはホスティング・アプリケーションの内部に埋め込む必要がありません。このため、リモートで配置でき、事前デプロイ済のホスティング・アプリケーションで使用できます。EJBジョブは、事前デプロイ済のホスティング・アプリケーションを含むどのホスティング・アプリケーションからも起動できます。EJBの実装は、スケジューラ・サーバーと同じWebLogicドメイン内にある必要があることに注意してください。

EJBは、Oracle Enterprise Scheduler (共有ライブラリ内で定義)で定義されているインタフェースに準拠しています。EJBは非トランザクションです。同期および非同期の両方のEJBジョブがサポートされます。非同期で実行するとEJBは即座に戻り、Oracle Enterprise Scheduler EJBは後でジョブの完了時に起動されます。EJB実装は、3つの共有ライブラリ・サーバー(oracle.ess)、クライアント(oracle.ess.client)およびシン・クライアント(oracle.ess.thin.client)のいずれとも動作可能です。シン・クライアント共有ライブラリは、Oracle Enterprise Schedulerデータ・ソースに依存しません。シン・クライアント・ライブラリの使用の詳細は、「シン・クライアント・アプリケーションの作成」を参照してください。

EJBはサブリクエストを発行でき、出力およびログに書き込むことができます。EJBインタフェースは、Javaジョブに類似しているか同じであり、類似の処理を実行できます。パフォーマンスを向上させるために、単一の共有EJBで複数のジョブ実装を統合できます。

EJBジョブは、EJBリモート・ビジネス・インタフェースを使用してリモートで実行されるJavaジョブです。実行タイプはJAVA_TYPEです。リモート・ジョブとは、リモート・サーバーにデプロイされているEJBです。このBeanのリモート・ビジネス・インタフェースは、oracle.as.scheduler.RemoteExecutableインタフェースを拡張し、executeメソッドを定義します。Oracle Enterprise Schedulerとサービス・コンポーネント間の契約は、executeメソッドで定義されます。図12-1は、標準的なEJBジョブ・デプロイメント内のコンポーネントを示しています。

EJBは、ホスティング・アプリケーションと同じドメインに配置する必要があり、SubjectオブジェクトはEJBに伝播されます。JNDIルックアップ操作で、オプションの資格証明を指定できます。デフォルト・アイデンティティは、anonymousです。

12.2 ジョブ開発の計画

Oracle Enterprise Schedulerは柔軟であり、実装およびデプロイメント・オプションが用意されています。「ジョブ開発の計画」は、ジョブ開発およびデプロイメント・プロセスの計画方法の概要を説明しています。

12.3 EJBジョブ・タイプのジョブ定義の作成および格納

Oracle Enterprise SchedulerでEJBタイプのジョブを使用するには、メタデータ・サービスを特定してジョブ定義を作成する必要があります。ジョブ定義は、名前とジョブ・タイプを指定して作成します。ジョブ定義を作成するときには、特定のシステム・プロパティも設定する必要があります。

ジョブ定義は、メタデータ・サービスを使用してメタデータ・リポジトリに格納できます。サンプル・メタデータ・ファイルは、この章の後半で説明します。

メタデータ・サービスの使用方法の詳細は、「メタデータ・サービスの使用」を参照してください。

ジョブ定義のJobTypeを指定する場合、JobTypeに関連付けられる特性を定義するSystemPropertiesを指定することもできます。表12-1および表12-2に、リクエストの処理方法を指定するプロパティを示します。

表12-1 EJBジョブ・タイプのプロパティ

プロパティ名[SystemPropertyクラスのフィールド] 説明

SYS_EXT_jndiProviderUrl[JNDI_PROVIDER_URL]

オプション。リモート・サーバーのURLを指定します。EJBがリモートに配置されている場合にのみ必須です。

JndiProviderUrlは、実行時に解決されるトークンを含むように指定できます。

次に2つの例を示します。

  • ${WIRING:urn:oracle:fmw:soa:t3}

    このURNは実行時に解決され、実際のURL値がフェッチされます。

  • t3://localhost:19283

    この場合、localhostはEJBがデプロイされるホストであり、19283はサーバー・ポート番号です。

SYS_EXT_jndiMappedName[JNDI_MAPPED_NAME]

必須。リモートEJB実装のJNDIルックアップ名を指定します。

例: ejb/fileAdapter

SYS_EXT_ejbOperationName[EJB_OPERATION_NAME]

オプション。適切なビジネス・メソッドに分岐するEJBの実装で使用されるパス・スルー・パラメータを指定します。

例: manageFileAdapter

SYS_EXT_jndiCSFKey[JNDI_CSF_KEY]

EJBサーバーのJNDIツリーが保護されている場合のみ必須です。キーストア内のユーザー名とパスワードにマップされ、CSFの別名を指します。この特定のユーザー名/パスワードのペアは、JndiMappedName参照で保護されたJNDIにアクセスするために必要な資格証明です。

このプロパティは、RequestParametersオブジェクト、またはホスティング・アプリケーションのOracle Enterprise Scheduler構成のいずれかに追加できます。

ノート:

Oracle Enterprise Manager Fusion Middleware ControlまたはWLSTスクリプトを使用して、CSFキー別名をインストール後のステップとして構成できます。インストール後のステップの前に、キーストアのCSFマップをoracle.ess.securityのデフォルト値に設定できます。

表12-2に、RequestParametersオブジェクト、またはホスティング・アプリケーションのOracle Enterprise Scheduler構成のいずれかに追加できるプロパティを示します。テスト環境から本番環境に移行する際ジョブ定義はレプリケートされるため、本番環境で環境固有のデータをジョブ定義に入力しないでください。かわりに、このデータは、構成データとしてホスティング・アプリケーションで個別に入力する必要があります。Oracle Enterprise Schedulerのトークン置換および論理クラスタ機能では、T2Pプロセス中にターゲット・デプロイメントに正しく適合するよう簡単に変更できるようにメタデータを抽象化できます。これらの機能の使用の詳細は、「トークンおよび論理クラスタの使用」を参照してください。

表12-2 追加プロパティ

プロパティ名[SystemPropertyクラスのフィールド] 説明

SYS_EXT_essJndiCsfKey[ESS_JNDI_CSF_KEY_NAME]

オプション。認証済Oracle Enterprise SchedulerサーバーのCSFキーの別名を指定します。このプロパティは、Oracle Enterprise SchedulerのJNDIツリーが認証済の場合にのみ必須です。

例: ess-jndi-csf-key

SYS_EXT_essRuntimeJndiMappedName{ESS_RUNTIME_JNDI_MAPPED_NAME]

ホスティング・アプリケーションで定義され、Oracle Enterprise SchedulerサーバーのJNDIツリーにバインドされる、Oracle Enterprise Scheduler RuntimeService BeanのJNDIのマップされた名前を指定します。

このプロパティは、EssNativeHostingApp以外のホスティング・アプリケーションを使用し、そのリモートBeanがOracle Enterprise SchedulerのランタイムBeanの呼出し(たとえば、出力の書込みまたは情報の記録、リクエストの発行またはリクエストの操作)を必要とする場合にのみ必須です。

SYS_EXT_essMetadataJndiMappedName[ESS_METADATA_JNDI_MAPPED_NAME]

ホスティング・アプリケーションで定義され、Oracle Enterprise SchedulerサーバーのJNDIツリーにバインドされる、Oracle Enterprise Scheduler MetadataService BeanのJNDIのマップされた名前を指定します。

このプロパティは、EssNativeHostingApp以外のホスティング・アプリケーションを使用し、そのリモートBeanがOracle Enterprise SchedulerのメタデータBeanへのアクセスを必要とする場合にのみ必須です。

SYS_EXT_essAsyncRequestJndiMappedName[ESS_ASYNC_REQUEST_JNDI_MAPPED_NAME]

ホスティング・アプリケーションで定義され、Oracle Enterprise SchedulerサーバーのJNDIツリーにバインドされる、Oracle Enterprise Scheduler AsyncRequest BeanのJNDIのマップされた名前を指定します。

このプロパティは、次の場合にのみ必須です。

  • EJB呼出しが非同期

  • EssNativeHostingApp以外のホスティング・アプリケーションを使用している場合

  • リモートBeanがOracle Enterprise SchedulerのBeanにコールバックする必要がある(たとえば、非同期コールバック)

システム・プロパティの詳細は、「パラメータとシステム・プロパティの使用」を参照してください。

12.4 保護された起動

リモートEJBの保護された起動は、そのサーバーのJNDIツリーが認証されている場合に必須です。これは、保護された参照を使用してリモートEJBがOracle Enterprise Scheduler EJBをコールバックする場合も同様です。次の各項で、ガイドラインを示します。

12.4.1 転送起動

次の内容が転送起動に適用されます。

  • Oracle Enterprise SchedulerがリモートEJBを起動する場合、実行ジョブのサブジェクトは常に伝播されます。

  • Oracle Enterprise Schedulerがジョブを実行する際、現在のOracle Enterprise Scheduler ServerのJndiProviderUrlRequestParametersを介してリモートEJBに常に提供されます。

  • リモート・サーバーのJNDIツリーが認証されている場合、JNDI_CSF_KEYプロパティをリクエスト・パラメータまたはホスティング・アプリケーションのEssConfigurationで指定する必要があります。

  • Oracle Enterprise Schedulerは、CsfKeyのキーストアを参照してPasswordCredentialを取得し、リモート・サーバーに接続します。

12.4.2 コールバック起動

次の内容がコールバック起動に適用されます。

  • リモートEJBがOracle Enterprise SchedulerのBeanにコールバックする必要がある場合、次のプロパティを指定できます。

    • HostingAppで公開されているOracle Enterprise SchedulerのRuntimeMetadataおよびAsyncRequest BeanのJNDI名は、リクエスト・パラメータまたはホスティング・アプリケーションのEssConfigurationで指定する必要があります。EssNativeHostingAppが使用されている場合、これらのエントリは必要がありません。

    • Oracle Enterprise SchedulerサーバーのJNDIツリーが認証されている場合、ESS_JNDI_CSF_KEY_NAMEプロパティをリクエスト・パラメータまたはホスティング・アプリケーションのEssConfigurationで指定する必要があります。Oracle Enterprise Schedulerにより、このプロパティがRequestParametersを介してリモートEJBで使用可能になります。

  • リモートEJBは、RemoteConnector APIを使用して、 Oracle Enterprise Scheduler Beanのリモート・インスタンスを取得できます。これは、次を渡すことで実行できます。

    • RequestParameters

    • BeanのRequestParametersおよびJndiMappedName (ネイティブ・ホスティング・アプリケーション以外のホスティング・アプリケーション用)

    • RequestParameters、ユーザー名およびパスワード(Oracle Enterprise Schedulerサーバーが認証されている場合)

    • InitialContext (主にEssNativeHostingAppを伴うJava SEクライアント用)

    • InitialContextおよびjndiMappedName (主にその他のホスティング・アプリケーションを伴うJava SEクライアント用)

12.4.3 RemoteConnector APIおよびサーバー・アフィニティ・プロパティ

コードの実装がOracle Enterprise Scheduler EJBへのアクセスに依存している場合、RemoteConnector APIクラスで公開されているメソッドを使用します。Oracle Enterprise Schedulerでは、JNDIルックアップを実行する前にサーバー・アフィニティ・プロパティをInitialContext環境で設定する必要があり、RemoteConnector APIクラスがこのプロパティを設定します。これは、マルチノード・クラスタ・シナリオで特に重要です。RemoteConnectorクラスは、Oracle Enterprise Schedulerクライアント・ライブラリでパッケージ化されています。

何らかの理由でRemoteConectorクラスを使用できない場合、次の例に示すように、Oracle Enterprise Scheduler EJBの参照を実行する前に環境マップ・プロパティをInitialContextに設定できます。

if(PlatformUtils.isWebLogic())
   envProps.put("weblogic.jndi.enableServerAffinity", "true");

マルチノード・クラスタ環境では、クラスタ・アルゴリズムをラウンドロビン・アフィニティに設定するのが最適です。

12.4.4 リモート・サーバーからのCSF参照

Oracle Enterprise SchedulerサービスのBeanが認証されている場合、リモート・アプリケーションは、保護された参照を使用してOracle Enterprise Schedulerにコールバックする必要があります。リクエスト・パラメータで使用可能なESS_JNDI_CSF_KEY_NAMEプロパティを使用するOracle Enterprise SchedulerのRemoteConnector APIを使用して、参照を実行できます。ただし、このCSF参照を支援するために、RemoteConnectorを起動するコードは資格証明ストア・アクセスの権限を付与する必要があります。次のXMLの一部分を、リモート・アプリケーションのjazn-data.xmlファイルに追加できます。

 <jazn-policy>
    <grant>
      <grantee>
        <codesource>
          <url>file:${domain.home}/servers/${weblogic.Name}/tmp/ 	                _WL_user/<AppName>/-</url>
        </codesource>
      </grantee>
      <permissions>
      <permission>           <class>oracle.security.jps.service.credstore.CredentialAccessPermission
          </class>
          <name>context=SYSTEM,mapName=oracle.ess.security,keyName=*</name>
          <actions>READ</actions>
        </permission>
        <permission>
          <class>oracle.security.jps.JpsPermission</class>
          <name>IdentityAssertion</name>
          <actions>execute</actions>
        </permission>
        <permission>
          <class>oracle.security.jps.JpsPermission</class>
          <name>AppSecurityContext.setApplicationID.*</name>
        </permission>
      </permissions>
    </grant>
  </jazn-policy>  

12.5 同期Bean

この項では、同期Beanの作成方法を表す例を示します。

12.5.1 メタデータ

この項では、同期Beanに適用されるメタデータを示します。

次の例で、ファイルoracle/apps/ess/custom/Jobs/EssGatewayJobDefn.xmlにあるEJBジョブのジョブ定義のサンプルを示します

<?xml version = '1.0'?>
<job-definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                  xmlns="http://xmlns.oracle.com/scheduler"
                name="SoaEjbJobDefn"
                job-type="/oracle/as/ess/core/JobType/SyncEjbJobType.xml">
<description/>
  <display-name>EssGatewayBean</display-name>
  <parameter-list>
    <parameter name="SYS_EXT_jndiKeyName" data-type="string" read-only="true">
      ejb/essGatewayBean</parameter>
    <parameter name="SYS_EXT_jndiProviderUrl" data-type="string"        read-only="true">URL</parameter>
    <parameter name="SYS_EXT_ejbOperationName" data-type="string"  
      read-only="true">activateFileAdapter</parameter>
    <parameter name="SYS_effectiveApplication" data-type="string">
      ESS_NATIVE_HOSTING_APP_LOGICAL_NAME</parameter>
  </parameter-list>
</job-definition>
 

12.5.2 EJBジョブ・サンプル・コード

この項では、Oracle Enterprise Schedulerで予期される同期EJBジョブのサンプル実装を示します。

次のコード・スニペットは、このBeanを定義するejb-jar.xml ファイルの一部を示しています。

<session>
																      <description>ESS Gateway Bean</description>
      <ejb-name>EssGateway</ejb-name>
      <ejb-class>com.soa.beans.EssGatewayBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>     
      <security-identity>
        <use-caller-identity/>
      </security-identity>
</session>

次のコード・スニペットは、このBeanを定義するweblogic-ejb-jar.xml ファイルの一部を示しています。

<weblogic-enterprise-bean>
      <ejb-name>FileAdapterBean</ejb-name>
      <stateless-session-descriptor>
         <business-interface-jndi-name-map>
            <business-remote>oracle.as.scheduler.RemoteCancellableExecutable
         </business-remote>
            <jndi-name>ejb/essGatewayBean</jndi-name>
         </business-interface-jndi-name-map>
      </stateless-session-descriptor>
 </weblogic-enterprise-bean>
import javax.ejb.Stateless;
import oracle.as.scheduler.SystemProperty;
import oracle.as.scheduler.ExecutionCancelledException;
import oracle.as.scheduler.ExecutionErrorException;
import oracle.as.scheduler.ExecutionPausedException;
import oracle.as.scheduler.ExecutionWarningException;
import oracle.as.scheduler.RemoteCancellableExecutable;
import oracle.as.scheduler.RequestExecutionContext;
import oracle.as.scheduler.RequestParameters;
 
@Stateless(name = "EssGateway", mappedName = "ejb/essGatewayBean")
public class EssGatewayBean implements RemoteCancellableExecutable
{
    public EssGatewayBean()
    {
    }
   
    public void execute(RequestExecutionContext context,
                    RequestParameters parameters) throws ExecutionErrorException,
                    ExecutionWarningException, ExecutionCancelledException,
                    ExecutionPausedException
    {
        //Get the value of 'SYS_EXT_ejbOperationName' property
        String opName = (String)parameters.getValue(SystemProperty.EJB_OPERATION_NAME);
 
        if("manageFileAdapter".equals(opName))
        {
            //
            //Call business method of this bean or some other bean
            //
            //Hint: User defined properties can be set in RequestParameters while
            //submitting the job and can be retrieved here for further processing.
        }
    }
 
    public void cancel(RequestExecutionContext context,
                    RequestParameters parameters)
    {
        //
        //Logic to cancel the execution of a business method.
        //
        // Execute the actual logic of cancellation, notifies back to ESS
        // by throwing ExecutionCancelledException through execute method.
    }
}

12.6 非同期Bean

Oracle Enterprise SchedulerがBeanを非同期に起動する際、実行メソッドの終了を待機しません。このため、Beanの実装は処理が終了した後にOracle Enterprise Schedulerに通知する必要があります。この目的のためにRemoteAsyncHelperクラスを使用できます。または、RemoteConnectorから取得されるAsyncRequestBeanを使用して、ステータスの更新をOracle Enterprise Schedulerに通知できます。

通常、非同期EJBは次の用途に使用されます。

  • 長時間実行されている操作

  • プロセッサを大量に消費するタスク

  • バックグラウンド・タスク

  • アプリケーション・スループットを向上させる場合

  • メソッドの起動結果が即座に必要ではないときにアプリケーション・レスポンス時間を改善する場合

同期EJBジョブは、実行時間が短いユーザー・ビジネス・メソッドにより適しています。

Oracle Enterprise SchedulerがBeanを非同期で実行するにはいくつかの方法があります。

  • 明示的非同期性: 同期ステートレスBeanを使用して、メッセージドリブンBeanを非同期で起動します。(Java Message Serviceメッセージを、メッセージドリブンBeanによってリスニングされているトピック/キューに追加します)

  • 暗黙的非同期性: 非同期で動作するように、EJB非同期注釈を使用してビジネス・メソッド(実行、取消しメソッド以外)を宣言します。

ノート:

Oracle Enterprise Schedulerは、同期Beanを非同期で起動できます。ただし、このメソッドを使用する場合、長時間実行メソッドが非同期性のためにマークされる方法でBeanをモデル化する必要があります。

ノート:

EJB標準で定義されているように、executeメソッドは許可されていないカスタム例外をスローするため、executeメソッドの@Asynchronous注釈またはクラス全体を使用できません。Oracle Enterprise Schedulerでは、カスタム例外をスローするためにexecuteメソッドが必要です。

12.6.1 メタデータ

この項では、非同期Beanに適用されるメタデータを示します。

この例では、ファイルoracle/apps/ess/custom/Jobs/AsyncJobDefn.xmlにあるEJBジョブのジョブ定義のサンプルを示します

<?xml version = '1.0'?>
<job-definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.oracle.com/scheduler" name="EssAsyncJobDefn"
	job-type="/oracle/as/ess/core/JobType/AsyncEjbJobType.xml">
  <display-name>EssGatewayBean</display-name>
  <parameter-list>
    <parameter name="SYS_EXT_jndiKeyName" data-type="string" 
       read-only="true">ejb/essAsyncGatewayBean</parameter>
    <parameter name="SYS_EXT_jndiProviderUrl" data-type="string" 
      read-only="true">t3://localhost:10801</parameter>
    <parameter name="SYS_EXT_ejbOperationName" 
      data-type="string"read-only="true">activateFileAdapter</parameter>
    <parameter name="SYS_effectiveApplication" data-type="string">
      ESS_NATIVE_HOSTING_APP_LOGICAL_NAME</parameter>
  </parameter-list>
</job-definition>

12.6.2 EJBジョブ・サンプル・コード

この項では、「非同期Bean」で説明している明示的および暗黙的メソッドの両方を使用して非同期性を実装する方法を表すサンプル・コードを示します。

12.6.2.1 メッセージドリブンBeanを使用した非同期性の実装サンプル

次のコード・サンプルでは、メッセージドリブンBeanを非同期で起動するために使用される同期ステートレスBeanを示します。

package com.soa.test;
 
import java.io.Serializable;
import java.util.ArrayList;
import javax.ejb.Stateless;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
 
import javax.naming.InitialContext;
 
import oracle.as.scheduler.AsyncRequestBeanRemote;
import oracle.as.scheduler.ExecutionCancelledException;
import oracle.as.scheduler.ExecutionErrorException;
import oracle.as.scheduler.ExecutionPausedException;
import oracle.as.scheduler.ExecutionWarningException;
import oracle.as.scheduler.RemoteCancellableExecutable;
import oracle.as.scheduler.RequestExecutionContext;
import oracle.as.scheduler.RequestParameters;
import oracle.as.scheduler.request.RemoteConnector;
 
@Stateless(name = "EssAsyncPilot")
public class EssAsyncPilotBean implements RemoteCancellableExecutable 
{
	public EssAsyncPilotBean() {
	}
 
	public void execute(RequestExecutionContext requestExecutionContext,
			RequestParameters requestParameters)
			throws ExecutionErrorException, ExecutionWarningException,
			ExecutionPausedException, ExecutionCancelledException {
		// Delegate the job request cancellation to message driven bean
		postToQueue("execute", requestExecutionContext, requestParameters);
	}
 
	public void cancel(RequestExecutionContext requestExecutionContext,
			RequestParameters requestParameters) {
		RemoteConnector connector = new RemoteConnector();
		AsyncRequestBeanRemote asyncRequest;
 
		// Delegate the job request cancellation to message driven bean
		try {
			postToQueue("cancel", requestExecutionContext, requestParameters);
		} catch (Exception e) {
			//Mark this request as ERRORed
		}
		/*
		 * Other ways to cancel the job request.
		 * asyncRequest = connector.getAsyncRequestEJB(requestParameters);
		 * asyncRequest.onCancel(requestExecutionContext);
		 *
		 * (or)
		 *
		 * asyncRequest = connector.getAsyncRequestEJB(requestParameters);
		 * asyncRequest.setRequestStatus(
		 *      requestExecutionContext, AsyncStatus.CANCEL, "Cancelling the job");
		 *
		 * (or simply)
		 *
		 * RemoteAsyncHelper asyncHelper = new RemoteAsyncHelper(
		 *      requestExecutionContext, requestParameters);
		 * asyncHelper.onCancel();
		 *
		 */
	}
 
	private void postToQueue(String instruction,
			RequestExecutionContext context, RequestParameters params) {
		try {
			QueueConnectionFactory qconFactory;
			QueueConnection qcon;
			QueueSession qsession;
			QueueSender qsender;
			Queue queue;
			ObjectMessage msg;
			InitialContext ic = new InitialContext();
 
			qconFactory = (QueueConnectionFactory) ic
					.lookup("EssAsyncJmsConnFactory");
			qcon = qconFactory.createQueueConnection();
			qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
 
			queue = (Queue) ic.lookup("EssAsyncJmsQueue");
 
			qsender = qsession.createSender(queue);
			msg = qsession.createObjectMessage();
			qcon.start();
 
			ArrayList<Serializable> objsList = new ArrayList<Serializable>(2);
			objsList.add(context);
			objsList.add(params);
			objsList.add(instruction);
			msg.setObject(objsList);
			qsender.send(msg);
 
			System.out.println("The message, " + instruction
					+ ", has been sent to the EssAsyncJmsQueue.");
			qsender.close();
			qsession.close();
			qcon.close();
		} catch (Exception e) {
			System.out.print("error " + e);
		}
	}
}
import java.util.List;
import java.io.Serializable;
import javax.ejb.MessageDriven;
 
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
import oracle.as.scheduler.RequestExecutionContext;
import oracle.as.scheduler.RequestParameters;
import oracle.as.scheduler.async.RemoteAsyncHelper;
 
/**
 * This message driven bean sample relies on execute/cancel instructions.
 * Upon completion of execution or cancellation, this bean notifies
 * ESS about its status so that the job request is marked for completion.
 */
@MessageDriven(mappedName = "ejb/essAsyncJms")
public class EssAsyncJmsBean implements MessageListener {
    public void onMessage(Message message) {
        if (message instanceof ObjectMessage) {
            ObjectMessage objMessage = (ObjectMessage)message;
            try {
                List<Serializable> objsList = (List<Serializable>)objMessage.getObject();
                RequestExecutionContext ctx = (RequestExecutionContext)objsList.get(0);
                RequestParameters params = (RequestParameters)objsList.get(1);
                String instruction = (String)objsList.get(2);
                RemoteAsyncHelper asyncHelper = new RemoteAsyncHelper(ctx, params);
                if ("cancel".equalsIgnoreCase(instruction)) {
                    //EssAsyncJmsBean.cancel: Cancelling the Execution
                    try {
                        //Do the actual cancellation
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    asyncHelper.onCancel();
                    //EssAsyncJmsBean.cancel: Completed cancellation
                } else {
                    //EssAsyncJmsBean.execute: Started the Execution ");
                    try {
                        //Do the actual execution
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                    asyncHelper.onSuccess();
                    //EssAsyncJmsBean.execute: Completed the Execution ");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
12.6.2.2 注釈を使用した非同期性の実装サンプル

次のコード・スニペットでは、EJB Asynchronousを使用して、Beanまたはそのメソッドが非同期に動作するように宣言します。

package com.soa.test;
 
import java.util.concurrent.Future;
 
import javax.annotation.Resource;
 
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
 
import javax.xml.transform.Result;
 
import oracle.as.scheduler.ExecutionCancelledException;
import oracle.as.scheduler.ExecutionErrorException;
import oracle.as.scheduler.ExecutionPausedException;
import oracle.as.scheduler.ExecutionWarningException;
import oracle.as.scheduler.RemoteExecutable;
import oracle.as.scheduler.RequestExecutionContext;
import oracle.as.scheduler.RequestNotFoundException;
import oracle.as.scheduler.RequestParameters;
import oracle.as.scheduler.RuntimeServiceException;
import oracle.as.scheduler.SchedulerException;
import oracle.as.scheduler.async.RemoteAsyncHelper;
 
@Stateless(name = "EssAsyncAnnotatedBean", mappedName = "ejb/essAsyncAnnBean")
public class EssAsyncAnnotatedBean implements RemoteExecutable {
    @Resource
    SessionContext sessionContext;
 
    public void execute(RequestExecutionContext requestExecutionContext,
                        RequestParameters requestParameters) throws 
    ExecutionErrorException, ExecutionWarningException,
    ExecutionPausedException,ExecutionCancelledException 
    {
        RemoteAsyncHelper asyncHelper = null;
 
        try {
            asyncHelper = new RemoteAsyncHelper(requestExecutionContext, requestParameters);
            
            //Initiate processing
            initiateProcessing(requestExecutionContext, requestParameters);
 
            //Get processed results
            Future<Result[]> results = getProcessedResults(requestExecutionContext, requestParameters);
 
            //do further processing
 
            //Finally, complete the request
            asyncHelper.onSuccess();
        } 
        catch (Exception e) 
        {
            try 
            {
                asyncHelper.onBizError(e.getMessage());
            } 
            catch (Exception f) 
            {
            }
        }
    }
 
    @Asynchronous
    public void initiateProcessing(RequestExecutionContext requestExecutionContext,
                                   RequestParameters requestParameters) 
    {
        //startProcessing
    }
 
    @Asynchronous
    public Future<Result[]> getProcessedResults(RequestExecutionContext requestExecutionContext,
                                                RequestParameters requestParameters) 
    {
        Result[] resultsArr = null;
        //do processing
        return new AsyncResult<Result[]>(resultsArr);
    }
 
}