EJB 3.0カスタム・インターセプタの開発方法

日付:2006年5月10日
著者:Jason Haley

はじめに

このデモ・アプリケーションは、EJB 3.0に対するオラクルのサポートについて、インターセプタの使用を中心に説明します。

EJB 3.0インターセプタを使用すると、Bean開発者は、メソッド呼出しフローに対してきめ細かな制御を行えます。 インターセプタは、ステートレスSession Bean、ステートフルSession Bean、Message-Driven Beanで使用できます。 インターセプタは、同じBeanクラスまたは外部クラスにあるメソッドです。 すべてのEJBに対するデフォルトのインターセプタをejb-jarモジュールで定義できます。

Bean開発者は、インターセプタを使用して次の処理を実行できます。

  • Beanに渡される前のパラメータの変更
  • Beanから返された値の変更
  • メソッド例外の捕捉と吸収
  • コールへの完全な割込み(独自のセキュリティ・フレームワークに有効)
  • メソッド・プロファイリングの提供など

ここでは、HelloWorld EJBを使用して、ステートレスSession Beanの簡単なインターセプタの例をいくつか示します。 checkPermissionインターセプタ・メソッドはBeanクラスで定義され、 ProfilingInterceptorは外部クラスとして定義されます。 また、デフォルトのインターセプタを定義する方法についても学習します。

インターセプタを使用したステートレスSession Beanの例


HelloWorld EJBからの次のコードは、Beanクラスでのインターセプタ・メソッドの使用と、外部クラスでのインターセプタ・メソッドの使用を示します。

package oracle.ejb30;
import javax.interceptor.*;
import javax.ejb.*;
@Stateless
@Interceptor(ProfilingInterceptor.class)
public class HelloWorldBean implements HelloWorld {
@Resource private javax.ejb.SessionContext ctx;
  public void sayHello() {
    System.out.println("Hello!");
  }

  @AroundInvoke
  public Object myInterceptor(InvocationContext ic) throws Exception {
    System.out.println("checkPermission interceptor invoked");
    if (!userIsValid(ctx.getCallerPrincipal())) {
      throw new SecurityException("Caller: '" +
      ctx.getCallerPrincipal().getName() +
      "' does not have p ermissions for method " +
      ic.getMethod());
    }
    return ic.proceed();
  }
}

次のコードは、 HelloWorld EJBの外部インターセプタ・クラスとして機能する、 ProfilingInterceptorクラスのコードです。

package oracle.ejb30;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class ProfilingInterceptor {

     @AroundInvoke
     public Object profile(InvocationContext ctx) throws Exception {
            System.out.println("profile interceptor invoked");
            long startTime = 0;
           try {
                  startTime = System.currentTimeMillis();
                 return ctx.proceed();
            } finally {
                 System.out.println("Method " + ctx.getMethod() +
                 " executed in " +
                 (System.currentTimeMillis() - startTime)
                 + "ms");
            }
         }
   }

注意:

@Interceptorアノテーションは、別のクラスで定義されたインターセプタを指定します。 複数のインターセプタが必要な場合は、かわりに @Interceptorsアノテーションを使用します。

@AroundInvokeアノテーションは、インターセプタとして機能するメソッドを指定します。 このようなメソッドは1つのInvocationContextパラメータを必要とし、オブジェクトを返します。

インターセプタは、Beanレベルまたはメソッド・レベルで定義できます。 次に、EJBモジュールにデフォルトのインターセプタを定義する方法について説明します。

インターセプタを使用したステートレスSession Beanの例

デフォルトのインターセプタは、全EJBの全Beanメソッドに対してEJB-JARモジュールで起動します。 デフォルトのインターセプタは、デプロイメント・ディスクリプタで定義されます。

<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>oracle.ejb30.DefaultInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>

前提条件

必須知識

アプリケーションのサンプルを完了させるには、以下を熟知している必要があります。
  • EJB 3.0

EJB 3.0の詳細は、OTNの次のドキュメントを参照してください。

ソフトウェア要件

このデモンストレーションでは、次のソフトウェア・コンポーネントがインストールされ、正しく構成されている必要があります。

表記法

  • %ORACLE_HOME% - Oracle Application Server 10g 10.1.3をインストールしたディレクトリ
  • %JAVA_HOME% - 使用するJDKがインストールされているディレクトリ
  • %HOWTO_HOME% - デモンストレーションを解凍したディレクトリ

アプリケーションの構築

このアプリケーションのJavadoc は、 %HOWTO_HOME%/doc/javadoc/ディレクトリにあります。

構成ファイルは %HOWTO_HOME%/etcディレクトリにあり、application.xmlなどのデプロイメント・ディスクリプタ・ファイルが含まれます。

アプリケーションの実行

Oracle Application Server 10g 10.1.3.1のスタンドアロンのインスタンスでアプリケーションのサンプルを実行するには、次の手順に従ってください。

1. サンプルのファイル・ディレクトリの検証

  • build - ビルド時に作成される一時ディレクトリ
  • log - ビルド/デプロイのログを保持する一時ディレクトリ
  • etc - アプリケーションをパッケージ化するのに必要なすべてのファイル
  • lib - 配置可能なアプリケーション・アーカイブを保持
  • doc - How-toドキュメントとJavadoc
    • javadoc - 異なるソース・ファイルのJavadoc
    • how-to-ejb30-interceptor.html - このHow-toページ
  • src - デモンストレーションのソース
    • ejb - インターセプタのサンプル・コードの格納先
    • client - アプリケーション・クライアント・コードの格納先

2. 環境の設定

次の環境変数が定義されていることを確認してください。

  • %ORACLE_HOME% - Oracle Containers for J2EEをインストールしたディレクトリ
  • %JAVA_HOME% - JDKをインストールしたディレクトリ
  • %PATH% - %ORACLE_HOME% /ant/binを含む

3. サーバーの起動

以上を変更した後に、次のコマンドを使用してOracle Containers for J2EEをスタンドアロンで起動します。

>%ORACLE_HOME%/bin/oc4j -start

Oracle Application Server管理インストールを使用している場合、上記の変更後に次のコマンドを使用します。

> %ORACLE_HOME%/opmn/bin/opmnctl startall

4. アプリケーションの生成、コンパイル、および配置

Ant 1.6.2はOracle Containers for J2EEに同梱されており、 PATH環境変数を $ORACLE_HOME/ant/binに設定する必要があります。 オペレーティング・システムによっては、現在はAntが環境変数をサポートしていないものがあります。 該当するオペレーティング・システムの場合は、 %HOWTO_HOME% ディレクトリにあるant-oracle.xmlを修正してください。

demo directoryのant-oracle.propertiesを編集し、 次のOracle Containers for J2EEスタンドアロンで示されているとおりに、プロパティに正しい値が設定されていることを確認してください。

  • oc4j.host: Oracle Containers for J2EEが稼働しているホスト (デフォルトはlocalhost)
  • oc4j.admin.port: RMIポート番号(デフォルトは23791)
  • oc4j.admin.user: 管理ユーザー名(デフォルトはoc4jadmin)
  • oc4j.admin.password: 管理ユーザーのパスワード(デフォルトはwelcome)
  • oc4j.binding.module: 配置したWebモジュールがあるWebサイト名(デフォルトはhttp-web-site)

Oracle Application Server管理インストールを使用している場合、Oracle Application Serverのインストールにおいて管理されているOracle Containers for J2EEインスタンスの oc4j.admin.userおよび oc4j.admin.password以外の変更については、次のプロパティを変更します。

  • opmn.host: Oracle Application Serverが稼働しているhostname/IP (デフォルトはlocalhost)
  • opmn.port: Oracle Application Serverインストール時のOPMNリクエスト・ポート(デフォルトは6003)
  • oc4j.instance: 管理ユーザー名(デフォルトはoc4jadmin)

環境に応じて、ant-oracle.propertiesのdeployer.uriを適切にコメントアウトする必要があります。たとえば、OPMNの管理する単一のOracle Containers for J2EEインスタンスやクラスタ化されたOracle Containers for J2EEインスタンス/グループなどです。

環境に合わせて、 jndi.propertiesのprovider.url、principalおよびcredentialの変更が必要です。 Oracle Application Serverインストールを使用している場合は、provider.urlを次の形式で使用してください。 opmn:ormi://localhost:6003:home/ejb30interceptor.

アプリケーションを構築するには、 %HOWTO_HOME%ディレクトリで次のコマンドを入力します。

>ant

これで、 %HOWTO_HOME%/libディレクトリ内に ejb30interceptor.earが新しく作成されます。

構築に成功すると、このコマンドはアプリケーションをデプロイするよう試みます。 まず、OC4Jが稼働しているかをテストします。

アプリケーションは、別々にデプロイすることもできます。 %ORACLE_HOME%の環境変数が定義されていることを確認したら、 %HOWTO_HOME%ディレクトリから次のコマンドを入力します。

>ant deploy

5. アプリケーションの実行

次のコマンドを実行してサンプルを実行します。名前をプログラム引数として使用します。

>ant run

Oracle Containers for J2EEを起動したコンソールに戻ると、HelloWorld EJBのインターセプタ・メソッドが生成した出力が表示されています。

まとめ

このドキュメントで学習した内容は、次のとおりです。

  • EJB 3.0を使用した、ステートレスSession Beanの簡単なインターセプタ・メソッドの開発および定義
  • Oracle Application Server 10g 10.1.3を使用した、インターセプタ・メソッドでの簡単なステートレスSession Beanの配置および実行