RMIレジストリ・サービス・プロバイダ
Java Naming and Directory Interface (JNDI)

目次


はじめに

RMIレジストリ・サービス・プロバイダを使用して、JNDIアプリケーションからRMIレジストリに登録されているリモート・オブジェクトにアクセスできます。プロバイダにレジストリの位置を渡すと、そのレジストリに登録されているオブジェクトにバインドされたネーミング・コンテキストが作成されます。このコンテキストは、JNDIからアクセス可能なほかの名前空間(LDAPなど)にバインドされます。各リモート・オブジェクトへの参照も、同様にほかの名前空間にバインドされます。

レジストリ・コンテキストを他の名前空間にバインドすると、リモート・オブジェクトに対して、レジストリの位置に依存しないアクセスを行うことができます。RMIクライアントでは、レジストリのホスト名またはポート番号の情報は必要ありません。RMIサーバーでは、サーバーのサービスを潜在的なクライアントに通知するときに、この機能を利用できます。また、リモート・オブジェクトから、ユーザー、組織、およびネットワーク・リソースの情報にアクセスするときに使用される企業ディレクトリに対して、リンクを作成できます。

このサービス・プロバイダがインストールされている場合は、JNDIにjava.rmi.Namingクラスの機能が組み込まれます。

このドキュメントでは、RMIレジストリ・サービス・プロバイダの機能について説明します。


環境プロパティ

RMIレジストリ・サービス・プロバイダでは、次のJNDI環境プロパティが使用されます。環境プロパティ、システム・プロパティ、アプレット・パラメータ、およびリソース・ファイルを使用してプロパティがどのように初期化されるかについては、JNDIのドキュメントを参照してください。

java.naming.factory.initial

レジストリ・サービス・プロバイダを選択するときに、初期コンテキストとして使用されます。プロバイダでは使用されません。プロバイダの初期コンテキスト・ファクトリのクラス名を指定します。たとえば、

env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.rmi.registry.RegistryContextFactory");

このプロパティは、java.naming.provider.urlプロパティとともに使用されます。レジストリを初期コンテキストとして使用している場合は、このプロパティを設定する必要があります。ただし、初期コンテキストにURLだけを渡した場合は、このプロパティを指定する必要はありません。詳細は、「RMI URL」を参照してください。

java.naming.provider.url

レジストリが初期コンテキストとして使用されているときは、このプロパティにレジストリの位置を指定します。その値は、オブジェクト名コンポーネントを含まないRMI URLです(下の「RMI URLの形式」を参照)。たとえば、

env.put(Context.PROVIDER_URL, "rmi://server:1099");

このプロパティのデフォルト値は「rmi:」です。ローカル・ホストのポート1099上で動作するレジストリです。

このプロパティは、java.naming.factory.initialプロパティとともに使用されます。

java.naming.factory.state

状態ファクトリ・クラスの完全修飾名のリストです。コロンで区切られています。渡されたオブジェクトが格納されるときに、オブジェクトの状態を取得するために使用されます。このメカニズムを使用して、オブジェクトをレジストリに格納できる形式に変換できます。RMIレジストリ・サービス・プロバイダは、java.rmi.Remotejavax.naming.Reference、およびjavax.naming.Referenceableオブジェクトの格納をサポートします。詳細は、javax.naming.spi.NamingManager.getStateToBind()を参照してください。

java.naming.factory.object

オブジェクト・ファクトリ・クラスの完全修飾名のリストです。コロンで区切られています。レジストリから読み込まれたオブジェクトが変換されます。このメカニズムを使用して、オブジェクトをアプリケーションに適した形式に変換できます。詳細は、javax.naming.spi.NamingManager.getObjectInstance()を参照してください。

com.sun.jndi.rmi.factory.socket

このプロパティは、クライアント・ソケットを取得してRMIを呼び出すために、RMIランタイムで使用するソケット・ファクトリを指定します。ソケット・ファクトリに指定される値は、java.rmi.server.RMIClientSocketFactory型である必要があります。このプロパティが設定されていない場合、レジストリではデフォルトのソケット・ファクトリが使用されます。

java.naming.rmi.security.manager

このプロパティは、どの値に設定されていても、プロバイダがRMISecurityManagerをインストールを試みることを示します。下の「セキュリティについて」を参照してください。


名前

RMIレジストリでは、フラットな名前空間がサポートされます。階層がないため、すべての名前は基本要素です。名前には任意の文字を使用できます。大文字小文字が区別されます。

名前は、レジストリ・コンテキストのメソッドに引数として渡され、これらのメソッドの結果として、Nameオブジェクトまたは文字列のどちらかとして返されます。Nameオブジェクトを使用するときは、レジストリに渡される基本名を値として持つコンポーネントが1つ必要です。文字列が名前として使用されると、合成名の文字列表現として解釈されます。そのため、たとえばctxがレジストリ・コンテキストの場合、次の2つのバインド解除操作は同等です。

String name = ...
ctx.unbind(name);
ctx.unbind(new CompositeName(name));

合成名の解析中に特別に処理される4つのメタキャラクタ「/」、「\\」、「"」、「\'」のいずれかを含む名前には注意が必要です。これらの文字は、適切な方法でエスケープするか、引用符で囲む必要があります。たとえば、基本名X/Yは、XYをコンポーネントとして含む2つのコンポーネントから成る名前と間違われないように、合成名X\/Yとして表すことができます。詳細は、CompositeNameを参照してください。


RMI URL

JNDIでは、オブジェクトが指定されているURLの解決がサポートされます。そして、レジストリ・サービス・プロバイダでは、RMI URLを名前として使用できます。これにより、より汎用的なJNDIインタフェースのみを使用する、java.rmi.Naming機能の汎用性が向上します。

com.sun.jndi.url.rmi.rmiURLContextFactoryクラスは、RMI URLのURLコンテキスト・ファクトリを実装します。このため、デフォルトのJNDI初期コンテキストにRMI URLを名前として渡すことができます。


RMI URLの形式

RMI URLでは、次のどちらかの形式が使用されます。

   rmi://[host][:port][/[object]]

   rmi:[/][object]
オブジェクト名を指定しなかった場合は、指定したホストおよびポートのレジストリがURLに指定されます。そうでない場合は、指定したオブジェクト名の下のレジストリに登録されているリモート・オブジェクトが指定されます。

ホストを省略した場合は、ローカル・ホストが指定されているとみなされます。ポートを省略した場合は、デフォルト・レジストリのポート1099が指定されているとみなされます。


APIマッピング

レジストリ・サービス・プロバイダは、java.naming.Contextおよびjava.naming.Referenceableインタフェースを実装します。ContextおよびReferenceableメソッドは、下で説明されているレジストリ操作にマップされます。

lookup()
lookupLink()

java.rmi.Registry.lookup()メソッドが呼び出されます。返されたオブジェクトがjavax.naming.Referenceのラッパーである場合、参照されるオブジェクトはjavax.naming.spi.NamingManager.getObjectInstance()を使用して作成されます。JNDIリンクは、現在サポートされていません。

bind()

java.rmi.Registry.bind()メソッドが呼び出されます。最初に、javax.naming.spi.NamingManager.getStateToBind()によって状態ファクトリが参照されます。バインドするオブジェクトの型は、java.rmi.Remotejavax.naming.Reference、またはjavax.naming.Referenceableでなければなりません。オブジェクトがjavax.naming.Referenceまたはjavax.naming.Referenceableである場合、その参照はRemoteラッパー内にラップされてからバインドされます(下の「オブジェクトをレジストリにバインドする」を参照)。

rebind()

java.rmi.Registry.rebind()メソッドが呼び出されます。それ以外の場合、オブジェクトはJNDI bind()操作のように処理されます。

unbind()

java.rmi.Registry.unbind()メソッドが呼び出されます。

rename()

このメソッドは、JNDI操作のシーケンス(lookup()bind()unbind())として実装されます。シーケンスは、基本的には実行されません。

list()

java.rmi.Registry.list()メソッドが呼び出されます。このメソッドでは、バインドされたオブジェクトの型に関する情報は提供されないため、返される各javax.naming.NameClassPairのクラス名はジェネリックのjava.lang.Objectになります。

listBindings()

java.rmi.Registry.list()メソッドが呼び出されます。結果として得られた列挙からjavax.naming.Bindingが読み込まれるたびに、java.rmi.Registry.lookup()が呼び出され、javax.naming.spi.NamingManager.getObjectInstance()経由で渡されます。

createSubcontext()
destroySubcontext()

これらの操作はサポートされていません。

getNameParser()

大文字小文字を区別する基本名の場合に、名前パーサーが返されます。

getNameInNamespace()

空の文字列(レジストリの名前)が返されます。

composeName()

2つの名前の組み合わせが返されます。

addToEnvironment()

指定したプロパティが、コンテキストの環境に追加されます。java.naming.rmi.security.managerプロパティが追加された場合、プロバイダは、デフォルトのRMIセキュリティ・マネージャのインストールを試みます(「セキュリティについて」を参照)。その他のプロパティの環境への追加または変更を行うこともできますが、コンテキストには影響しません。

removeFromEnvironment()

指定したプロパティが、コンテキストの環境から削除されます。削除されなかった場合は、コンテキストに対する影響はありません。

close()

プロバイダによって使用されている内部状態がクリアされます。クリアされなかった場合は、直接の影響はありません。

getReference()

このコンテキストが参照で構築されている場合は、その参照の複製が返されます。それ以外の場合は、ホスト名を特定でき、それが「localhost」でなければ、そのコンテキストの新しい参照が返されます(下の「レジストリ・コンテキストとリモート・オブジェクトのバインディング」を参照)。


バインディング

オブジェクトをレジストリにバインドする

オブジェクトがjava.rmi.Remoteインタフェースを実装している場合は、そのオブジェクトをレジストリ・コンテキストにバインドできます。オブジェクトはまた、JNDI Referenceオブジェクトである場合や、Referenceableインタフェースを実装している場合にもバインドできます(その場合は、そのオブジェクト自体ではなく、対応する参照がバインドされます)。

レジストリ・コンテキストとリモート・オブジェクトのバインディング

各RMIレジストリ・コンテキストがReferenceableインタフェースを実装します。そのため、各コンテキストを、Referenceableオブジェクトを格納できるJNDIからアクセス可能な任意の名前空間にバインドできます。レジストリに登録されている各リモート・オブジェクトへの参照も構築されます。このとき、そのオブジェクトを他の名前空間にバインドできます。

com.sun.jndi.rmi.registry.RegistryContextFactoryクラスは、レジストリ参照を対応するレジストリ・コンテキストまたはリモート・オブジェクトに変換するオブジェクト・ファクトリを実装します。

レジストリ・コンテキストを構築する場合は、レジストリのURLが識別できなければなりません。このURLは、java.naming.provider.urlプロパティから取得されるか、初期コンテキストに名前として渡されるか、またはレジストリ参照に埋め込まれていることがあります。URLにホスト名が含まれていないか、またはホスト名「localhost」が使用されている場合、レジストリ・コンテキストのgetReference()メソッドはコンテキストの参照を返すことができません。そのため、このようなレジストリ・コンテキストを別の名前空間にバインドすることはできません。

レジストリ参照の形式

RMIレジストリのJNDI参照には、それぞれに「URL」型のタグが付けられた、文字列アドレス(StringRefAddrクラス)のリストが含まれています。各アドレスには、レジストリかレジストリに登録されているリモート・オブジェクトのどちらかを示すRMI URLが含まれています(上の「RMI URLの形式」を参照)。

複数のURLが1つの参照に含まれるときは、各URLは同一の論理リソースの代替アドレスです。アドレスの順番は重要ではありません。StringRefAddrクラスでないアドレスや、「URL」のアドレス型でないアドレスは無視されます。


使用例

プログラム例1

レジストリにアクセスする初期コンテキストを作成するには、上の「環境プロパティ」の説明に従って、java.naming.factory.initialおよびjava.naming.provider.urlプロパティを設定します。レジストリに格納された名前は、次のように出力されます。

Context ictx = new InitialContext(env);
NamingEnumeration enum = ictx.list("");

プログラム例2

プログラム例1のプロパティを使用しないで、RMI URLを名前として渡し、デフォルトの初期コンテキストで解決します。

Context registryCtx = (Context)ictx.lookup("rmi://host");

プログラム例3

レジストリ・コンテキストは、JNDIにアクセス可能なほかの名前空間にバインドされます。たとえば、前の例のregistryCtxをLDAPディレクトリにバインドするには、次のようにします。

Context ldapCtx = (Context)ictx.lookup("ldap://server/o=sun,c=us");
ldapCtx.bind("cn=rmi", registryCtx);
名前R1R2がこのレジストリにバインドされている場合、LDAP名前空間をブラウズしているJNDIクライアントでは、cn=rmiエントリの下にR1R2が表示されます。

プログラム例4

RMIレジストリに登録されているリモート・オブジェクトは、そのオブジェクトに対する参照を構築すると、JNDIにアクセス可能なほかの名前空間にバインドされます。変数objに前の例のR1という名前のオブジェクトが保持されている場合は、それを次のようにLDAPディレクトリにバインドできます。

RefAddr addr = new StringRefAddr("URL", "rmi://host/R1");
Reference ref = new Reference(obj.getClass().getName(), addr);
ldapCtx.bind("cn=R1", ref);

セキュリティについて

セキュリティ・マネージャ

通常のRMIセキュリティが適用されます。RMIを使用してリモート・サーバーのクラスを動的にロードするには、まずセキュリティ・マネージャをインストールする必要があります。セキュリティ・マネージャは、ほかのRMIアプリケーションと同じ方法でインストールできます。Java Remote Method Invocationの仕様を参照してください。または、java.naming.rmi.security.manager環境プロパティがプロバイダに渡された場合、プロバイダはRMISecurityManager自体をインストールしようとします。

アクセス権

JNDIおよびRMIレジストリ・プロバイダを使用するアプリケーションには、次のアクセス権が必要です。

permission java.net.SocketPermission "host[:port]", "connect";

java.naming.provider.urlプロパティ、およびコンテキスト・メソッドに指定されているURL文字列名で識別される各ホスト/ポート用のアクセス権です。

permission java.net.SocketPermission "host[:port]", "connect,accept";

javax.naming.References内のURL文字列で識別される各ホスト/ポート用のアクセス権です。

permission java.lang.RuntimePermission "setSecurityManager";

RMIレジストリ・プロバイダにRMISecurityManagerをインストールするよう依頼する、java.naming.rmi.security.manager環境プロパティを使用している場合。


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.