ヘッダーをスキップ
Oracle Containers for J2EEサービス・ガイド
10g(10.1.3.5.0)
B56027-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

2 JNDIの使用

この章では、Oracle Containers for J2EE(OC4J)によって実装されるJava Naming and Directory Interface(JNDI)サービスについて説明します。この章では、JNDIの初期コンテキストの設定方法と、JNDIルックアップの実行方法に重点を置いて説明します。

この章には、次の項目が含まれます。

この章の情報を使用するには、JNDIとJNDI APIに関する基本的な知識が必要です。チュートリアルやAPIドキュメントなど、JNDIに関する基本情報は、Sun社の次のWebサイトを参照してください。

http://java.sun.com/products/jndi/index.html

他のJNDIクラスおよびメソッドの詳細は、次のJavadocを参照してください。

http://java.sun.com/products/jndi/1.2/javadoc/index.html

JNDIタスク

この章では、次の一般的なJNDIタスクについて説明します。

新機能

次のOC4J JNDIの機能および動作は、今回のリリースの新機能です。

追加ドキュメント

次のサイトにあるHow-Toドキュメントでは、OC4Jの機能に関する情報(各機能の概要や機能に関連するコードの抜粋など)を提供しています。

http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html

JNDIの概要

JNDIは、J2EE仕様の核となる部分です。JNDIにより、J2EEアプリケーションと各コンポーネントにネーミングおよびディレクトリ機能が提供されます。JNDIは、特定のネーミングまたはディレクトリ・サービス実装とは関係なく定義されます。これにより、J2EEアプリケーションと各コンポーネントは、単一のAPIを使用して異なるネーミングおよびディレクトリ・サービスにアクセスできます。この共通APIの背後にネーミングとディレクトリの異なるサービス・プロバイダ・インタフェース(SPI)をプラグインすると、様々なネーミング・サービスを処理できます。

J2EEアプリケーション開発者は、JNDIを使用してネーミング・コンテキストを取得します。ネーミング・コンテキストにより、アプリケーションは、データソース、ローカルおよびリモートEnterprise JavaBeans(EJB)、JMSトピックやキューなどのJ2EEリソースを使用できます。

初期コンテキストの作成と使用

最も頻繁に行われるJNDI操作は、次の2つです。

OC4Jは、起動時に各アプリケーションのデプロイメント・ディスクリプタのリソース参照を読み取ることによって、各アプリケーションのJNDI初期コンテキストを構成します。

永続性

初期構成後の各アプリケーションのJNDIネームスペースは、完全にメモリー・ベースです。コンテキストに対して実行時に追加された内容は、永続化されません。

OC4Jが停止すると、プログラム的に(たとえば、Context.bindのコールにより)作成されたバインディングは、使用できなくなります。

J2EEデプロイメント・ディスクリプタを通じて宣言的に指定されたバインディングは、アプリケーション・サーバーの停止後も維持されます。

JNDIコンテキストの構成

OC4Jは、サーバーにデプロイされた各アプリケーション用のJNDIコンテキストを構成します。OC4Jサーバーには、少なくとも1つのアプリケーション(グローバル・アプリケーション)が常に存在します。このアプリケーションは、サーバー・インスタンス内の各アプリケーションに対するデフォルトの親です。ユーザー・アプリケーションは、グローバル・アプリケーションからプロパティとバインディングを継承します。ユーザー・アプリケーションでは、グローバル・アプリケーションで定義されたプロパティ値のオーバーライド、プロパティに対する新しい値の指定、および必要に応じた新しいプロパティの定義が可能です。ユーザー・アプリケーションのコンテキストのルックアップは、次の順序で実行されます。

  • 最初に、ローカル・アプリケーションのネームスペースが調べられます。

  • バインディングがローカルで見つからない場合、親アプリケーションのバインディングが調べられます。

  • バインディングがローカルまたは親アプリケーションで見つからない場合、次のいずれかの処理に分岐します。

    • グローバル・ルックアップが有効の場合、OC4Jインスタンスに現在デプロイされている既知のすべてのアプリケーション・コンテキストを対象にルックアップの解決が試みられます。

    • グローバル・ルックアップが無効の場合(デフォルトの動作)、NameNotFoundExceptionがスローされます。


注意:

JNDIネームスペースへのアクセスを保護する方法の詳細は、『Oracle Application Serverセキュリティ・ガイド』を参照してください。

グローバルJNDIルックアップの有効化

グローバルJNDI機能を使用すると、OC4Jインスタンスの既知のすべてのアプリケーションを対象にルックアップが試行されます。現在のアプリケーション内でのルックアップに失敗した場合、デプロイされた各アプリケーションのコンテキストを対象にルックアップが試行されます。特定の名前で最初に成功したルックアップ結果が戻されます。この機能は、デフォルトで無効になっています。

グローバルJNDI機能を有効化するには、次のようにします。

  1. テキスト・エディタを使用して、J2EE_HOME/config/server.xmlを開きます。

  2. <application-server>要素内にglobal-jndi-lookup-enabled属性を追加して、trueに設定します。

    <application-server
       global-jndi-lookup-enabled="true">
       ...
    </application-server>
    
  3. server.xmlを保存して閉じます。

  4. アプリケーション・サーバーを再起動します。


注意:

各リソースのバインディング名が、OC4Jインスタンスにデプロイされたすべてのアプリケーションにおいて一意である必要があります。また、すべてのアプリケーションに対するルックアップが実行される場合、アプリケーションの順序は保証されません。同じインスタンス内の2つのアプリケーションに異なるオブジェクトを指し示す同じ名前のバインディングが存在すると、ルックアップによって予期しないオブジェクトが戻される可能性があります。

クラスパスの構成

ターゲット・アプリケーションのクラスは、JNDIルックアップを実行するアプリケーションのクラスパスに存在する必要があります。クラスパスの構成時には、次のオプションがサポートされています。

  • OC4J共有ライブラリの一部としてターゲット・ライブラリを含めます。これにより、OC4Jは、すべてのデプロイ済アプリケーションによってインポートされるシステム・ライブラリとしてJARをロードします。より厳密にシステム・ライブラリを制御する場合は、名前付きシステム・ライブラリとしてターゲット・クラスをデプロイし、これらのライブラリを明示的に各アプリケーションにインポートすることも可能です。

    シリアライズできないJavaオブジェクト、またはリモートで使用できないJavaオブジェクト(ローカル・オブジェクト)では、共有ライブラリを使用する必要があります。また、コール元およびターゲット・アプリケーションの両方にインポートする必要があります。


    注意:

    共有ライブラリの作成の詳細は、『Oracle Containers for J2EE開発者ガイド』を参照してください。

  • ターゲットJARファイルをコール元のEARファイルに含めます。コール元のEARファイルにターゲットJARをコピーすると、そのJARを次のいずれかの方法で適切なクラスパスにロードできるようになります。

    • サーブレットからグローバル・ルックアップが実行される場合は、EAR内にデプロイされているWebアプリケーション・ファイル(WAR)のWEB-INF/libディレクトリにターゲットJARを配置します。

    • EJBビジネス・メソッドからグローバル・ルックアップが実行される場合は、コール元アプリケーションのトップレベルのEARファイルにターゲットJARを配置します。コール元のJARのマニフェストにClass-Pathタグを追加して、クラスパスにターゲットJARを追加します。

      次に、(コール元のJARファイルのMETA-INFディレクトリに存在する)必要なマニフェスト・ファイルの例を示します。

      "Manifest-Version: 1.0
      Class-Path: jndi_globalLookup-ejb2.jar"
      

      この例のClass-Path行には、ターゲットJAR(この例ではjndi_globalLookup-ejb2.jar)がコール元EJBのクラスパスにロードされるよう指定されています。

環境およびコンストラクタ

OC4JがJNDI初期コンテキストの構成に使用する環境は、次の3つの場所にあります。

  • java.util.Hashtableインスタンスで明示的に指定された環境。JNDI初期コンテキスト・コンストラクタに渡されます(このコンストラクタのコード例は、「例: EJBをルックアップするアプリケーション・クライアント」を参照してください)。

  • システム・プロパティ値。OC4Jサーバーまたはアプリケーション・コンテナによって設定されます。

  • jndi.propertiesファイル。(アプリケーション・クライアントのJARファイルの一部として)アプリケーションのEARファイルに含まれます。

JNDIのInitialContextには、次の2つのコンストラクタがあります。どちらのコンストラクタを使用しても、初期コンテキストを作成できます。

InitialContext()
InitialContext(Hashtable env)

InitialContext()

InitialContext()コンストラクタでは、デフォルトのコンテキスト環境を使用してContextオブジェクトが作成されます。OC4Jのサーバー・サイド・アプリケーションでこのコンストラクタを使用すると、起動時にOC4Jによって構成されたアプリケーション・コンテキストが戻されます。このコンストラクタは、通常、JSP、EJBおよびサーブレットなど、サーバー・サイドで実行されるコードで使用されます。

InitialContext(Hashtable env)

InitialContext(Hashtable env)コンストラクタでは、環境パラメータが使用されます。この形式のInitialContextコンストラクタは、通常、JNDI環境を指定する必要があるリモート・クライアント・アプリケーションで使用されます。このコンストラクタのenvパラメータはjava.util.Hashtableで、JNDIに必要なプロパティが含まれます。表2-1に、javax.naming.Contextインタフェースで定義されるこれらのプロパティを示します。

表2-1 InitialContextのプロパティ

プロパティ 意味

java.naming.factory.initial

INITIAL_CONTEXT_FACTORY

新規の初期コンテキスト・オブジェクトの作成時にどの初期コンテキスト・ファクトリを使用するかを指定します。有効な設定は次のとおりです。

  • oracle.j2ee.rmi.RMIInitialContextFactory

  • oracle.j2ee.naming.ApplicationClientInitialContextFactory

  • oracle.j2ee.iiop.IIOPInitialContextFactory

非推奨のコンテキスト・ファクトリの詳細は、この表の下にある「注意」を参照してください。

java.naming.provider.url

PROVIDER_URL

サーバー上のオブジェクトをルックアップするためにクライアント・サイドJNDIコードで使用されるURLを指定します。詳細は、表2-2「JNDI関連の環境プロパティ」を参照してください。

java.naming.security.principal

SECURITY_PRINCIPAL

現在のセキュリティ資格証明のユーザー名を指定します。アプリケーション・クライアント・コードでクライアントを認証するために必要です。サーバー・サイドのコードでは、認証はすでに実行されているため必要ありません。

java.naming.security.credential

SECURITY_CREDENTIALS

現在のセキュリティ資格証明のパスワードを指定します。アプリケーション・クライアント・コードでクライアントを認証するために必要です。サーバー・サイドのコードでは、認証はすでに実行されているため必要ありません。


これらのプロパティを設定し、新規JNDI初期コンテキストを取得するコード例は、「例: EJBをルックアップするアプリケーション・クライアント」を参照してください。


注意:

次のコンテキスト・ファクトリは非推奨です。
  • com.evermind.server.rmi.RMIInitialContextFactory

  • com.evermind.server.ApplicationClientInitialContextFactory

  • com.oracle.iiop.server.IIOPInitialContextFactory

非推奨のコンテキスト・ファクトリ名と置き換えられる新しいファクトリ名の詳細は、表2-1「InitialContextのプロパティ」java.naming.factory.initialの説明を参照してください。


例: EJBのルックアップ

次の例は、一般的なWebまたはEJBアプリケーションにおいて、サーバー・サイドで使用されるコードです。

Context ctx = new InitialContext();
HelloHome myhome = (HelloHome) ctx.lookup("java:comp/env/ejb/myEJB");

最初の文は、デフォルト環境を使用して新規の初期コンテキスト・オブジェクトを作成します。2番目の文は、アプリケーションのJNDIツリーでEJBホーム・インタフェース参照をルックアップします。

この場合、myEJBは、web.xml(このコードがサーブレットで実行される場合)またはejb-jar.xml(このコードがEJBビジネス・メソッドで実行される場合)で宣言されているセッションBeanへの参照の名前です。この参照は、<ejb-ref>タグで定義されます。次に、EJB参照は、このコードを実行するコール元に応じて、orion-web.xmlまたはorion-ejb-jar.xmlの実際のJNDIロケーションにマップされます。

例:

<ejb-ref>
  <ejb-ref-name>ejb/myEJB</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <home>myEjb.HelloHome</home>
  <remote>myEjb.HelloRemote</remote>
</ejb-ref>

JNDIコンテキストおよびスレッド

デフォルトでは、ユーザー名とパスワードを使用してJNDIコンテキストを作成すると、OC4Jでの初期コンテキストの構成時に、プリンシパルまたはユーザーがコンテキスト・インスタンスにバインドされます。これにより、OC4Jネームスペースでの名前付きオブジェクトのルックアップ、リモート・オブジェクトへの参照の取得、およびリモート・オブジェクトに対する操作の起動を実行する場合、認証およびアクセス制御において指定のプリンシパルまたはユーザーが使用されます。この使用例では、1つのアプリケーション・クライアント内の複数のスレッドで、コンテキストが共有される可能性があります。

プリンシパルまたはユーザーは、作業を実行するスレッドと関連付けることも可能です。これを行うには、適切なプリンシパルおよび資格証明のプロパティ値を使用してコンテキストを作成します。スレッドとプリンシパルの関連付けを解除するには、コンテキストをクローズします。

スレッドがプリンシパルと関連付けられると、そのプリンシパルは、関連付けられたスレッドのデフォルトになります。その後、プリンシパルまたは資格証明プロパティなしでコンテキストが作成されても、スレッドに関連付けられたプリンシパルは変化しません。

単一のコンテキストを複数のスレッドで共有することは、技術的には可能ですが、別のスレッドにコンテキストを渡しても、そのコンテキストの作成に使用されたプリンシパルは新規スレッドに関連付けられません。プリンシパルを新規スレッドに関連付ける唯一の方法は、そのスレッド内で新規コンテキストを作成することです。また、コンテキストは、それが作成されたスレッド内でのみクローズできます。これらの理由のため、特定のコンテキストで実行されるすべての作業は、同じスレッド内で処理することをお薦めします。

1つのスレッドは、任意の時点において、ただ1つのプリンシパルと関連付けることができます。どのコンテキストもクローズせずに、単一のスレッド内で複数のコンテキストを作成した場合、そのスレッドは、最後に作成されたコンテキストで使用されているプリンシパルと関連付けられます。プリンシパル情報は、スレッドとともにスタックに格納されます。最後のコンテキストがクローズされると、スレッドは、その前のコンテキストの作成に使用されたプリンシパルと関連付けられ、その後も同様に処理されます。

この機能を有効化するには、コマンドラインでシステム・プロパティの-DAssociateUserToThread=trueを設定します。デフォルトでは、この機能は無効です(falseに設定されています)。

他のベンダーのコンテキストの作成

クライアントが、異なるベンダーのサーバー(WebLogicサーバーなど)にあるリモート・リソースにアクセスすることも考えられます。InitialContext(Hashtable env)コンストラクタを使用し、JNDI環境プロパティをベンダーが要求する値に設定して、初期コンテキストを作成することができます。ただし、一部の環境プロパティが、ベンダーの特定の値を持つシステム・レベルのJNDIプロパティとして設定されたままになる可能性があります。その場合、誤ったシステム・レベル・プロパティが使用されるため、引数のないInitialContext()コンストラクタを使用してそれ以降に作成されたOC4Jコンテキストが失敗する可能性があります。

こうした事例に対処するため、OC4JではURLコンテキスト・ファクトリが提供され、それにより、システム・レベル・プロパティとして設定されたままの可能性があるベンダーのJNDI環境設定がOC4Jコンテキストで使用されないようにしています。URLコンテキスト・ファクトリは、サーバー・サイド・クライアントとリモート・クライアントのどちらでも利用できます。

サーバー・サイドURLコンテキスト・ファクトリの有効化

サーバー・サイド・クライアントは、サーバー環境プロパティを設定することで、URLコンテキスト・ファクトリを有効化することができます。アプリケーションで異なるベンダーのコンテキストが使用される場合は常に、URLコンテキスト・ファクトリを有効化することをお薦めします。

サーバー・サイドURLコンテキスト・ファクトリを有効化する手順

  1. OC4Jを停止します。

  2. テキスト・エディタを使用して、J2EE_HOME/config/server.xmlファイルを開きます。

  3. environment-naming-url-factory-enabledプロパティを追加して、trueに設定します。例:

    <application-server ...
       ...
       <environment-naming-url-factory-enabled="true" />
       ...
    </application-server>
    
  4. OC4Jを再起動します。

リモート・クライアントURLコンテキスト・ファクトリの有効化

リモート・クライアントは、初期コンテキストを作成するときに指定されたJNDI環境プロパティを使用して、リモート・クライアントURLコンテキスト・ファクトリを有効化することができます。リモート・クライアントが別のベンダーのコンテキストを使用した後にOC4Jルックアップを実行するとエラーが発生する場合、このプロパティを設定することをお薦めします。

次の例に、リモートURLコンテキスト・ファクトリ・プロパティを指定する初期コンテキストを示します。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"factory_class");
env.put(Context.PROVIDER_URL,"protocol://remote_host:port/app");
env.put(Context.SECURITY_PRINCIPAL,"user");
env.put(Context.SECURITY_CREDENTIALS,"password");
env.put(Context.URL_PKG_PREFIXES, "oracle.j2ee.jndi.client");

Context ctx = new InitialContext(env);

WebLogic Serverリソースへのアクセス

この項では、OC4Jコンポーネント(サーバー・クライアントまたはリモート・クライアント)が、EJBなどのリソースにアクセスするために、JNDIを使用してWebLogicサーバーに接続する方法について説明します。


注意:

OC4JとWebLogicサーバーの間の相互接続性には、次の内容は含まれません。
  • トランザクション伝播: クラスタ内のサーバー間でのトランザクション・コンテキスト・オブジェクトの伝播は、独自の機能です。たとえば、OC4Jで開始されたトランザクションは、リモート・コール時にWebLogicに伝播されません。WebLogicサイドで開始されたトランザクションについても同じです。

  • セキュリティ・コンテキスト伝播: クラスタ内のサーバー間でのセキュリティ情報やアイデンティティ情報の伝播は、独自の機能です。つまり、セキュリティ・サブジェクトやセキュリティ・アイデンティティを、OC4JとWebLogicを通じて共有することはできません。


OC4JクライアントからWebLogicリソースにアクセスする手順

  1. クライアント・コードで、WebLogicの初期コンテキストを作成します。続いて、コンテキストを使用してリソースをルックアップし、使用します。例:

    Hashtable env = new Hashtable();
    env.put("java.naming.factory.initial",
    "weblogic.jndi.WLInitialContextFactory");
    env.put("java.naming.provider.url","t3://host:7001");
    env.put("java.naming.security.principal","user");
    env.put("java.naming.security.credentials","password");
    
    Try {
       Context ctx = new InitialContext(env);
       Object homeObject =
       context.lookup("EmployeeBean");
       //use the EmployeeBean
    }
    catch (NamingException e) {
    // a failure occurred
    }
    finally {
       try {ctx.close();}
       catch (Exception e) {
       // a failure occurred
       }
    
  2. 前の項(「サーバー・サイドURLコンテキスト・ファクトリの有効化」および「リモート・クライアントURLコンテキスト・ファクトリの有効化」)の説明に従って、OC4J URLコンテキスト・ファクトリ・プロパティを設定します。

  3. https://metalink.oracle.com(My Oracle Support)からoc4j-wls-interop.jarをダウンロードし、クライアントのクラスパスに含めます。OC4Jサーバー・サイド・クライアントの場合、それを行うには、JARファイルをOC4J共有ライブラリとして追加します。『Oracle Containers for J2EEデプロイメント・ガイド』の「共有ライブラリの作成と管理」を参照してください。

  4. クライアントを起動するか、デプロイします。

JNDIコンテキストの参照

JNDIブラウザを使用すると、JNDIネームスペース全体を参照して、オブジェクトの特定のセットがアプリケーションで実際にバインドされていることを確認できます。

JNDIブラウザは、Oracle Enterprise Manager 10g Application Server Controlコンソール内で次のようにアクセスできます。

JNDIブラウザへのパス

「OC4J: ホーム」→「管理」タブ→「タスク名: サービス」→「JNDIブラウザ」→「タスクに移動」アイコンをクリック→「すべてを開く」

JNDIバインディングを文字列として取得する手順

JNDIコンテキストのバインディングは、文字列表現としても取得できます。これは、デバッグに役立つ場合があります。

「OC4J: ホーム」→「管理」タブ→「タスク名: システムMBeanブラウザ」「タスクに移動」→「J2EEDomain:oc4j」、「J2EEServer:standalone」、「JNDIResource」にドリルダウン→「アプリケーションの選択」→「操作」タブ→「getBindingsAsString」または「getBindingsAsXMLString」→「起動」

J2EEアプリケーション・コンポーネントからのオブジェクトのルックアップ

この項では、JNDIを使用して、サーブレット、JSPページ、EJBなどのJ2EEアプリケーション・コンポーネントから、バインドされたオブジェクトをルックアップする方法について説明します。

OC4Jで初期コンテキスト・ファクトリを使用して、J2EEアプリケーション・コンポーネントから次のようにオブジェクトにアクセスできます。

同じアプリケーション内のオブジェクトのルックアップ

サーバーで実行されているコードは、アプリケーションの一部として定義されます。コードはアプリケーションの一部であるため、JNDIが使用するプロパティのデフォルトは、OC4Jにより設定されます。JNDIのInitialContextオブジェクトの構成時には、アプリケーション・コード(サーブレットやEJBビジネス・メソッドなど)でプロパティ値を指定する必要はありません。


注意:

アプリケーションでリモート参照(同じJVM内の別のJ2EEアプリケーションのリソースやJ2EEアプリケーションの外部のリソースなど)をルックアップする必要がある場合は、RMIInitialContextFactoryまたはIIOPInitialContextFactoryを使用する必要があります。「別のアプリケーション内のオブジェクトのルックアップ」を参照してください。

例: データソースをルックアップするサーブレット

この例では、データベース上でJDBC操作を実行するために、サーブレットでデータソースを取得します。

Application Server Controlコンソールを使用して、データソースの場所を指定します。「データ・ソースの作成」ページの「JNDIロケーション」フィールドに場所を指定します。第5章「データソース」を参照してください。

サーブレットのweb.xmlファイルで、次のリソースを定義します。

<resource-ref>
   <description>
      A data source for the database in which
      the EmployeeService enterprise bean will
      record a log of all transactions.
   </description>
   <res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
   <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

対応するorion-web.xmlのマッピングは次のとおりです。

<resource-ref-mapping name="jdbc/EmployeeAppDB" location="jdbc/pool/OracleCache" />

name値は、web.xml<res-ref-name>要素で指定されている値と同じです。

location値は、data-sources.xml<data-source>要素のjndi-name属性に対応しています。

この場合、サーブレットの次のコードによって、データソース・オブジェクトへの正しい参照が戻されます。

...
try {
  InitialContext ic = new InitialContext();
  ds = (DataSource) ic.lookup("java:comp/env/jdbc/EmployeeAppDB");
  ...
}
catch (NamingException ne) {
  throw new ServletException(ne);
}
...

同じアプリケーション内でオブジェクトをルックアップする場合、初期コンテキスト・ファクトリを指定する必要はありません。アプリケーションの起動時に、OC4Jによって適切なデフォルトが設定されるためです。通常、同じアプリケーション内のルックアップでは、InitialContextを作成するjavax.naming.InitialContextno-argsコンストラクタのみが必要です。

この場合、同じアプリケーション内またはjava:comp/の下に含まれているオブジェクトのルックアップにURLが必要ないため、プロバイダURLを指定する必要もありません。


注意:

一部のプラットフォームでは、JDKのバージョンによって、システム・プロパティjava.naming.factory.url.pkgsが自動設定され、com.sun.java.*が組み込まれることがあります。

このプロパティをチェックし、com.sun.java.*が存在している場合は削除してください。


別のアプリケーション内のオブジェクトのルックアップ

別のアプリケーション内のオブジェクトにアクセスする場合、またはスタンドアロンのJavaクライアントからJ2EEリソースにアクセスする場合、次のいずれかのコンテキスト・ファクトリを使用します。

  • oracle.j2ee.rmi.RMIInitialContextFactory

  • oracle.j2ee.iiop.IIOPInitialContextFactory

  • oracle.j2ee.naming.ApplicationClientInitialContextFactory

RMIInitialContextFactory

RMIInitialContexFactoryは、分散ルックアップのためにOracle Remote Method Invocation(RMI)プロトコルを使用するJNDIコンテキストの実装を提供します。このコンテキスト・ファクトリは、リモート・クライアントと、他のOC4Jインスタンスにデプロイされたバインディングをルックアップするアプリケーションによって使用されます。RMIInitialContextFactoryで使用されるJNDI環境プロパティの詳細は、表2-2「JNDI関連の環境プロパティ」を参照してください。RMIの詳細は、「Remote Method Invocationの使用方法」を参照してください。

例: RMIを使用してリモートからEJBをルックアップするサーブレット

この例では、サーブレットで、異なるマシンの別のOC4Jインスタンスで稼働するEJBにアクセスします。この例のEJBは、「例: EJBをルックアップするアプリケーション・クライアント」で使用されているEmployeeBeanです。

次のコードは、サーブレット・コードから抜粋したものです。

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"oracle.j2ee.rmi.RMIInitialContextFactory");
env.put("java.naming.provider.url","ormi://remotehost/bmpapp");
env.put("java.naming.security.principal","SCOTT");
env.put("java.naming.security.credentials","TIGER");
Context context = new InitialContext(env);
Object homeObject =
context.lookup("EmployeeBean");
例: 複数インスタンス環境でリモートからEJBをルックアップするサーブレット

iAS内でOC4Jを実行する場合、リモートJNDIサービスにより、リクエストでopmn:ormiプロトコルを使用するよう指定できます。これにより、クライアントでは、ORMIポート情報をハードコードせずにルックアップを試行できます。OC4J JNDIコードは、このiASインストールに適切なORMIポートを決定するために、opmnプロセスと通信します。ルックアップは前述のORMIの例と似ていますが、java.naming.provider.urlプロパティは、opmn:ormiで始まるURLに設定されます。次に、opmn:ormiを使用した同じルックアップ・コードの例を示します。

次のコードは、サーブレット・コードから抜粋したものです。

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"oracle.j2ee.rmi.RMIInitialContextFactory");
env.put("java.naming.provider.url","opmn:ormi://remotehost/bmpapp");
env.put("java.naming.security.principal","SCOTT");
env.put("java.naming.security.credentials","TIGER");
Context context = new InitialContext(env);
Object homeObject =
context.lookup("EmployeeBean");

opmn URLの参照先となるホーム・インスタンスを指定する方法もあります。opmnの使用方法の詳細は、「Remote Method Invocationの使用方法」を参照してください。

IIOPInitialContextFactory

IIOPInitialContextFactoryは、分散ルックアップのためにInternet Inter-ORB Protocol(IIOP)を使用するJNDIコンテキストの実装を提供します。RMIの詳細は、「Remote Method Invocationの使用方法」を参照してください。

IIOPInitialContextFactoryを使用する状況は、リモート・プロトコルがORMIではなくIIOPであることを除けば、RMIInitialContextFactoryのときと同様です。


注意:

IIOPInitialContextFactoryは、EJBのルックアップにのみ使用できます。この条件は、ApplicationClientInitialContextFactorycorbaname URLを使用する場合にも適用されます。

例: IIOPを使用してリモートからEJBをルックアップするサーブレット

次に例を示します。

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"oracle.j2ee.iiop.IIOPInitialContextFactory");
env.put("java.naming.provider.url","corbaname::remotehost:PORT_NUMBER#APPLICATION_NAME");
env.put("java.naming.security.principal","SCOTT");
env.put("java.naming.security.credentials","TIGER");
Context context = new InitialContext(env);
Object homeObject =
context.lookup("EmployeeBean");

この例では、corbaname URLは、EJBの場所を指定するのに使用されます。corbaname文字列で、PORT_NUMBERはOC4Jで使用するよう構成されているIIOPのポート番号、remotehostはOC4Jが稼働するサーバーの名前、APPLICATION_NAMEはEJBを含むアプリケーションの名前です。

この例で使用されるアプリケーションは、ルックアップが正常に機能するためには、IIOPが有効の状態でデプロイされている必要があります。また、リモート・クライアントには、OC4Jが生成したIIOPクライアントjarが含まれる必要があります。詳細は、「ORMIからIIOPトランスポートへの切替え」にあるOC4J IIOPに関する説明を参照してください。

J2EEアプリケーション・クライアントからのオブジェクトのルックアップ

この項では、アプリケーション・クライアントを構成して、OC4Jインスタンスの内部で稼働するオブジェクトにアクセスする方法について説明します。OC4Jアプリケーション・クライアント・コンテナの使用方法の詳細は、第9章「アプリケーション・クライアント・コンテナの使用方法」を参照してください。

リモートのJ2EEサーバー・アプリケーションで使用可能なリソースをアプリケーション・クライアントでルックアップする場合、クライアントは初期コンテキストの構成にoracle.j2ee.namingパッケージのApplicationClientInitialContextFactoryを使用します。


注意:

アプリケーションがJ2EEアプリケーション・クライアントの場合(すなわち、application-client.xmlファイルが存在する場合)は、クライアント・アプリケーションで使用されるプロトコル(ORMIまたはIIOP)に関係なく、常にApplicationClientInitialContextFactoryを使用する必要があります。プロトコル自体は、JNDIプロパティjava.naming.provider.urlで指定します。詳細は、表2-2「JNDI関連の環境プロパティ」を参照してください。

コンポーネントのリモート・アクセスとローカル・アクセスは、リモート・クライアントの観点からすると本質的に同じです。クライアントでは、プロバイダURLに応じてORMIまたはIIOPを使用できます。

OC4Jサーバーに接続するJavaコードで構成されるアプリケーション・クライアントについて考えてみます。たとえば、ワークステーションで実行されるクライアント・コードで、EJBなどのサーバー・オブジェクトに接続して、一部のアプリケーション・タスクを実行するとします。この場合、リモート・クライアントでは、プロパティjava.naming.factory.initialの値をoracle.j2ee.naming.ApplicationClientInitialContextFactoryに設定する必要があります。この値は、クライアント・コードで指定できます。または、アプリケーション・クライアントのJARファイルの一部であるjndi.propertiesファイルで指定することもできます。

リモート・オブジェクトにアクセスするために、ApplicationClientInitialContextFactoryは、注釈を使用してリソース・インジェクションを利用するか、META-INF/application-client.xmlファイルおよびMETA-INF/orion-application-client.xmlファイルを読み取ります。どちらのファイルも、アプリケーション・クライアントのJARファイルにあります。

環境プロパティ

ORMIプロトコルが使用されている場合、ApplicationClientInitialContextFactory表2-2に示すプロパティを環境から読み取ります。

表2-2 JNDI関連の環境プロパティ

プロパティ 意味

dedicated.rmicontext

このプロパティは、OC4Jで使用されなくなりました。このプロパティは、次の2つの理由により使用されていました。

  • ロード・バランシングを有効にするため。

  • 既知のORMIおよびJNDIの不具合を回避するため。

クライアント・サイドのORMIロード・バランシングを有効化するには、「ロード・バランシング」の項に記載されているプロパティを使用してください。

「ロード・バランシング」の項に記載されているプロパティは、このフラグをまだ必要とするいくつかのケースで使用できます。

java.naming.provider.url

ローカル・オブジェクトまたはリモート・オブジェクトの検索時に使用するURLを指定します。書式は次のいずれかです。

[opmn:|http:|https:]ormi://hostname/appname

または

 corbaname:hostname:port

corbaname URLの詳細は、「corbanameのURLの指定」を参照してください。

ORMIプロトコルを使用する場合、カンマ区切りのリストで(フェイルオーバー用の)複数のホストを指定できます。

java.naming.factory.url.pkgs

一部のプラットフォームでは、JDKのバージョンによって、システム・プロパティjava.naming.factory.url.pkgsが自動設定され、com.sun.java.*が組み込まれることがあります。

このプロパティをチェックし、com.sun.java.*が存在している場合は削除してください。

Context.SECURITY_PRINCIPAL

ユーザー名を指定します。このプロパティは、クライアント・サイドのコードでクライアントを認証するために必要です。サーバー・サイドのコードでは、認証はすでに実行されているため必要ありません。このプロパティ名は、java.naming.security.principalとしても定義されます。

Context.SECURITY_CREDENTIAL

パスワードを指定します。このプロパティは、クライアント・サイドのコードでクライアントを認証するために必要です。サーバー・サイドのコードでは、認証はすでに実行されているため必要ありません。このプロパティ名は、java.naming.security.credentialsとしても定義されます。


ロード・バランシング

大量のリクエストが予想される場合、OC4Jインスタンス間でリクエストのロード・バランシングを行うと有益である場合があります。ロード・バランシングは、oracle.j2ee.rmi.loadBalanceプロパティを使用して構成できます。このプロパティは、クライアントのjndi.propertiesファイル、またはクライアント・コードのハッシュテーブルで設定します。次の表に、oracle.j2ee.rmi.loadBalanceプロパティの値を示します。

表2-3 oracle.j2ee.rmi.loadBalanceプロパティの値

説明

client

指定した場合、クライアントは、通信全体に対する最初のルックアップで初期選択されたOC4Jプロセスと対話します。

context

クラスタ化されたOC4J環境のEJBにアクセスするWebクライアント(サーブレットまたはJSP)で使用されます。

指定した場合、InitialContext()が起動するたびに、ランダムに選択されたOC4Jインスタンスの新規Contextオブジェクトが戻されます。

lookup

クラスタ化されたOC4J環境のEJBにアクセスするスタンドアロン・クライアントで使用されます。

指定した場合、クライアントがContext.lookup()をコールするたびに、ランダムに選択されたOC4Jインスタンスの新規Contextオブジェクトが作成されます。


ロード・バランシングの詳細は、「ORMIリクエストのロード・バランシングの構成」を参照してください。

例: EJBをルックアップするアプリケーション・クライアント

この項では、アプリケーション・クライアントを構成して、OC4Jインスタンスの内部で稼働するEJBにアクセスする方法について説明します。

最初に、EJBをEmployeeBeanという名前でOC4Jにデプロイします。この名前は、ejb-jar.xmlで次のように定義されます。

<ejb-jar>
  <display-name>bmpapp</display-name>
  <description>
     An EJB app containing only one Bean Managed Persistence Entity Bean
  </description>
  <enterprise-beans>
     <entity>
        <description>no description</description>
        <display-name>EmployeeBean</display-name>
        <ejb-name>EmployeeBean</ejb-name>
        <home>bmpapp.EmployeeHome</home>
        <remote>bmpapp.Employee</remote>
        <ejb-class>bmpapp.EmployeeBean</ejb-class>
        <persistence-type>Bean</persistence-type>
        ...
     </entity>
  </enterprise-beans>
..
</ejb-jar>

EJB EmployeeBeanは、orion-ejb-jar.xml内のJNDIロケーションbmpapp/EmployeeBeanに次のようにバインドされます。

<orion-ejb-jar>
   <enterprise-beans>
       <entity-deployment name="EmployeeBean"
           location="bmpapp/EmployeeBean" table="EMP">
                        ...
       </entity-deployment>
                        ...
   </enterprise-beans>
           ...
</orion-ejb-jar>

アプリケーション・クライアント・プログラムは、EmployeeBean EJBを使用し、それをEmployeeBeanとして参照します。

リソース・インジェクションをリクエストするためにアプリケーション・クライアントのメイン・クラスで注釈を使用する方法とJNDI APIの使用方法を示す、アプリケーション・クライアント・プログラムからの抜粋を示します。

注釈の使用方法

public class Client {
   @EJB
      private static EmployeeHome home;
      public  static void main(String[] args) {


       // Create a new record.
       Employee rec = home.create(empNo, empName, salary);

       // call method on the EJB
       rec.doSomething();
       ...
   }

JNDI APIの使用方法

public static void main (String args[])
{
 ...
 Context context = new InitialContext();
 /**
  * Look up the EmployeeHome object. The reference is retrieved from the
  * application environment naming context (java:comp/env). The ejb reference is
  * specified in the assembly descriptor (META-INF/application-client.xml).
  */
 Object homeObject =
     context.lookup("java:comp/env/EmployeeBean");
 // Narrow the reference to an EmployeeHome.
 EmployeeHome home =
     (EmployeeHome) PortableRemoteObject.narrow(homeObject,
                                                EmployeeHome.class);
 // Create a new record.
 Employee rec = home.create(empNo, empName, salary);
 // call method on the EJB
 rec.doSomething();
 ...
}

次の行でコンテキストを作成するときに、ハッシュテーブルを渡していないことに注意してください。

Context context = new InitialContext();

これは、コンテキストがjndi.propertiesファイルから読み取られる値を使用して作成されるためです。この例では、次の内容が含まれています。

java.naming.factory.initial=    oracle.j2ee.naming.ApplicationClientInitialContextFactory
java.naming.provider.url=ormi://localhost/bmpapp
java.naming.security.principal=SCOTT
java.naming.security.credentials=TIGER

または、jndi.propertiesファイルを提供するかわりに、InitialContextのコンストラクタにハッシュテーブルを渡すこともできます。その場合、コードは次のようになります。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,    "oracle.j2ee.naming.ApplicationClientInitialContextFactory");
env.put("java.naming.provider.url","ormi://localhost/bmpapp");
env.put("java.naming.security.principal","SCOTT");
env.put("java.naming.security.credentials","TIGER");
Context initial = new InitialContext(env);

アプリケーション・クライアントのコードはEmployeeBean EJBを参照するため、このEJBをapplication-client.xmlファイルの<ejb-ref>要素で宣言する必要があります。

<application-client>
   <display-name>EmployeeBean</display-name>
   <ejb-ref>
       <ejb-ref-name>EmployeeBean</ejb-ref-name>
       <ejb-ref-type>Entity</ejb-ref-type>
       <home>bmpapp.EmployeeHome</home>
       <remote>bmpapp.Employee</remote>
   </ejb-ref>
</application-client>

EmployeeBean EJBが、orion-ejb-jar.xmlファイルでの構成に従って、JNDIロケーションbmpapp/EmployeeBeanに次のようにバインドされることに注意してください。アプリケーション・クライアント・プログラムで使用するEJB参照名は、EJBが実際にorion-ejb-jar.xmlでバインドされているJNDIロケーションにマップする必要があります。これは、orion-application-client.xmlファイルで次のように指定します。

orion-application-client.xml file:
<orion-application-client>
   <ejb-ref-mapping name="EmployeeBean" location="bmpapp/EmployeeBean" />
</orion-application-client>

application-client.xmlファイルおよびorion-application-client.xmlファイルの詳細は、『Oracle Containers for J2EE開発者ガイド』の付録A「OC4J固有のデプロイメント・ディスクリプタ」を参照してください。

例: IIOPを使用してEJBをルックアップするアプリケーション・クライアント

前の例では、アプリケーション・クライアントが、リソースをリモート・ルックアップするための基底プロトコルとしてORMIを使用しました。かわりに、リモート・プロトコルとしてIIOPを使用するようにアプリケーション・クライアントを構成できます。EmployeeBeanをルックアップするコードは、前の例と同様ですが、次の部分が異なります。

jndi.propertiesファイルは、IIOPがリモート・プロトコルとして使用されるという事実を反映するように変更する必要があります。これは、jndi.propertiesjava.naming.provider.urlシステム・プロパティで構成します。次に、IIOPを使用するよう構成された同じ例のjndi.propertiesファイルを示します。

java.naming.factory.initial=    oracle.j2ee.naming.ApplicationClientInitialContextFactory
java.naming.provider.url=corbaname::REMOTE_HOST:IIOP_PORT#bmpapp
java.naming.security.principal=SCOTT
java.naming.security.credentials=TIGER

または、IIOPを基底プロトコルとして使用するため、jndi.propertiesファイルを指定するかわりにInitialContextのコンストラクタにハッシュテーブルを渡すこともできます。その場合、コードは次のようになります。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.naming.ApplicationClientInitialContextFactory");
env.put("java.naming.provider.url","corbaname::REMOTE_HOST:IIOP_PORT#bmpapp");
env.put("java.naming.security.principal","SCOTT");
env.put("java.naming.security.credentials","TIGER");
Context initial = new InitialContext(env);

この例のようにアプリケーション・クライアントでハッシュテーブルを使用してJNDIプロパティを設定する場合、セキュリティ資格証明をシステム・プロパティとして設定する必要があります。IIOPインターセプターは、システム・プロパティを通じてクライアントの資格証明にアクセスする必要があります。このことは、jndi.propertiesファイルの使用時には自動的に行われます。JNDIフレームワークにより、これらのプロパティが自動的にシステム・プロパティとして設定されるためです。

プロパティをコード自体で設定する場合、次の行をクライアント・コードに追加する必要があります。

System.setProperty("java.naming.security.principal","SCOTT");
System.setProperty("java.naming.security.credentials ","TIGER");

jndi.propertiesファイルを使用する場合、またはプログラム的に処理する場合のいずれの例でも、次の要件を満たす必要があります。

  • REMOTE_HOSTは、OC4Jサーバーの稼働するサーバーの名前に設定する必要があります。

  • IIOP_PORTは、IIOPリクエストを処理するためにOC4Jで使用されるポート番号に設定する必要があります。

アプリケーション・クライアントでIIOPを使用する場合、アプリケーション・クライアント・コードやデプロイメント・ディスクリプタを変更する必要はありません。クライアントは、jndi.propertiesファイルの使用方法などについて、IIOPが適切に動作するよう構成する必要があります。

デプロイされている各EJBのIIOPスタブにアクセスするため、リモート・アプリケーション・クライアントでは、デプロイ済アプリケーションのIIOPクライアントjarをクラスパスに含める必要があります。

詳細は、「ORMIからIIOPトランスポートへの切替え」を参照してください。

JNDI状態レプリケーション

この項では、JNDI状態レプリケーションについて説明します。


注意:

JNDI状態レプリケーションでは、複数OC4J環境でのクラスタリングがサポートされます。

開発中のアプリケーションを複数OC4J環境で使用するための環境としてスタンドアロン・モードのOracle Application Serverを使用している場合、この項の情報は、その計画およびコーディング・プロセスに役立ちます。


この項には、次の項目が含まれます。

JNDI状態レプリケーションとは

JNDI状態レプリケーションにより、あるOC4Jクラスタの1つのOC4Jインスタンスにおけるコンテキストの変更が、そのクラスタに存在する他のすべてのOC4Jインスタンスのネームスペースにレプリケートされます。

JNDI状態レプリケーションが有効化されている場合は、1つのサーバー上でシリアライズ可能な値をアプリケーション・コンテキストに(リモート・クライアント、EJBまたはサーブレットを使用して)バインドし、それを別のサーバー上で読み取ることができます。

JNDI状態レプリケーションの有効化

JNDI状態レプリケーションは、アプリケーションごとに有効化されている必要があります。アプリケーションをデプロイするときに、アプリケーションのMETA-INFディレクトリにあるorion-application.xml<cluster>タグを追加できます。この種の構成により、各アプリケーションのクラスタリング・ステータスを制御できます。この<cluster>タグを追加することで、HTTP/EJBセッション・レプリケーションとJNDI状態レプリケーションが可能になります。

<cluster>要素は、クラスタリング構成のための単一のメカニズムとして機能します。<cluster>要素は、次のいずれかのファイルに追加できます。

  • ORACLE_HOME/j2ee/home/config/application.xmlファイル(グローバル・レベルでクラスタリングを構成する場合)。

  • アプリケーション固有のorion-application.xmlファイル(各アプリケーションにクラスタリングを構成する場合)。

<cluster>要素の構成で中心となるのは、次のサブ要素の指定です。

  • <replication-policy>サブ要素では、レプリケーションの発生するタイミングと、レプリケートするデータを制御します。

  • <protocol>サブ要素では、multicast(デフォルト)、peer-to-peerまたはdatabaseのうち、レプリケーションに使用するメカニズムを定義します。

次に、OC4JクラスタリングおよびJNDI状態レプリケーション構成の2つの例を示します。

例1:

この例では、マルチキャスト・ネットワークを使用して通信するようアプリケーションを構成します。クラスタ内のすべてのノードで同じマルチキャスト・ポートを使用することが重要です。

<cluster>
    <protocol>
        <multicast ip="230.230.0.30" port="45678" />
    </protocol>
</cluster>

例2:

この例では、JNDI状態レプリケーションにpeer-to-peerプロトコルを使用します。この例の場合、クラスタで稼働するすべてのノードが、管理対象iASインスタンスの一部である必要があります。このOracle Application Serverインスタンスは、OPMNによって制御されます。

<cluster>
    <replication-policy trigger="onRequestEnd" scope="modifiedAttributes" />
    <protocol>
        <peer>
            <opmn-discovery/>
        </peer>
    </protocol>
</cluster>

OC4Jクラスタリングの詳細は、『Oracle Containers for J2EE構成および管理ガイド』を参照してください。

JNDI状態レプリケーションの制限事項

JNDI状態レプリケーションに依存する場合は、次の制限事項を考慮してください。

クラスタ全体への変更の伝播

シリアライズできない値へのバインドは、クラスタ全体に伝播しません。

リモート・オブジェクトのバインド

アプリケーション・コンテキスト内でリモート・オブジェクト(通常はhomeまたはEJBオブジェクト)をバインドすると、そのJNDIオブジェクトはクラスタ全体で共有されますが、バインドされている最初のサーバーにシングル・ポイント障害となる部分が発生します。