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


コメントの送付先: jndi@java.sun.com

目次


はじめに

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() を参照してください。
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」を基本名として使用する場合は、複合名「X\/Y」と表現し、コンポーネント「X」および「Y」の 2 つで構成されるコンポーネント名と解釈されないようにします。詳細については、CompositeName を参照してください。

RMI URL

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

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


RMI URL の形式

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

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

   rmi:[/][object]
オブジェクト名を指定しなかった場合は、指定したホストおよびポートのレジストリが URL に指定されます。オブジェクト名を指定した場合は、指定したオブジェクト名の下のレジストリに登録されているリモートオブジェクトが 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 参照には、文字列アドレス (StringRefAddr クラス) のリストが含まれます。 各アドレスは、「URL」型に指定されます。各アドレスには RMI URL が含まれます。 この 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 にアクセス可能なほかの名前空間にバインドされます。ここでは、プログラム例 2 の registryCtx を LDAP ディレクトリにバインドします。

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

プログラム例 4

RMI レジストリに登録されているリモートオブジェクトは、そのオブジェクトに対する参照を構築すると、JNDI にアクセス可能なほかの名前空間にバインドされます。プログラム例 3 の「R1」という名前のオブジェクトが変数 obj に保持されている場合は、このオブジェクトは 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 アプリケーションと同じ方法でインストールできます。JavaTM Remote Method Invocation の仕様を参照してください。java.naming.rmi.security.manager 環境プロパティがプロバイダに渡される場合は、プロバイダによって RMISecurityManager がインストールされます。

Java 2 SDK におけるアクセス権

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

permission java.net.SocketPermission "host[:port]", "connect";
java.naming.provider.url プロパティ、およびコンテキストメソッドに渡された URL 文字列名に指定されている、各ホストまたはポートに対して割り当てられます。

permission java.net.SocketPermission "host[:port]", "connect,accept";
javax.naming.Reference の URL 文字列に指定されている、各ホストまたはポートに対して割り当てられます。

permission java.lang.RuntimePermission "setSecurityManager";
java.naming.rmi.security.manager 環境プロパティを使用している場合は、RMI レジストリプロバイダを使用するときに RMISecurityManager のインストールが要求されます。


Copyright © 1999 Sun Microsystems, Inc., All Rights Reserved.