このドキュメントでは、Java IDL 一時ネームサービス tnameserv の使用方法について説明します。Java IDL には、Object Request Broker Daemon (ORBD) も含まれています。ORBD は、ブートストラップサービス、一時ネームサービス、永続ネームサービス、およびサーバーマネージャーを含むデーモンプロセスです。Java IDL のすべてのチュートリアルでは ORBD を使用していますが、一時ネームサービスを使用する例では、orbd の代わりに tnameserv を使用できます。orbd ツールの詳細については、orbd のマニュアルページまたはORBD に含まれる Java IDL ネームサービスに関するトピックを参照してください。
ここでは、以下の項目について説明します。
CORBA の COS (Common Object Services) ネームサービスは、ファイルシステムがファイルに対してディレクトリ構造を提供しているのと同じように、オブジェクト参照に対してツリー構造のディレクトリを提供します。Java IDL の一時ネームサービスである tnameserv は、COS ネームサービスの仕様を単純な形で実装したものです。
オブジェクト参照は名前空間に名前で格納され、それぞれのオブジェクト参照と名前の組は、ネームバインディングと呼ばれます。ネームバインディングはネーミングコンテキストに組み込むことができます。ネーミングコンテキストはそれ自体がネームバインディングであり、ファイルシステムのサブディレクトリと同じ編成機能を持ちます。すべてのバインディングは初期ネーミングコンテキストに格納されます。名前空間において、初期ネーミングコンテキストは唯一の永続的バインディングです。それ以外のネーミングコンテキストは、Java IDL のネーミングサービスプロセスが停止し、再起動されると失われます。
アプレットまたはアプリケーションから COS ネームサービスを使用するためには、その ORB はネームサービスが動作しているホストのポートを知っているか、そのネームサービスの文字列化された初期ネーミングコンテキストにアクセスできなければなりません。ネームサービスは、Java IDL のネームサービスでもその他の COS 準拠のネームサービスでもかまいません。
Java IDL ネームサービスは、ネームサービスを使用するアプリケーションまたはアプレットより前に起動しておかなければなりません。Java IDL 製品をインストールすると、Java IDL ネームサービスを起動するスクリプト (Solaris: tnameserv) または実行可能ファイル (Windows NT: tnameserv.exe) が作成されます。バックグラウンドで動作するように、ネームサービスを起動してください。
特に指定しない場合、Java IDL ネームサービスは、ORB の resolve_initial_references() メソッドと list_initial_references() メソッドの実装に使用するブートストラッププロトコルに対してポート 900 で待機します。
tnameserv -ORBInitialPort nameserverport&
ネームサーバーポートを指定しない場合、デフォルトでポート 900 が使用されます。Solaris ソフトウェアの実行時は、1024 より小さいポートでプロセスを開始する場合、root ユーザーになる必要があります。このため、1024 と等しいか 1024 より大きいポートを使用することをお勧めします。1050 のように別のポートを指定し、ネームサービスをバックグラウンドで実行するには、UNIX コマンドシェルで次のように入力します。
tnameserv -ORBInitialPort 1050&
Windows の MS-DOS システムプロンプトでは、次のように入力します。
start tnameserv -ORBInitialPort 1050
ネームサーバーのクライアントには、新しいポート番号を知らせる必要があります。このため、ORB オブジェクトの作成時に org.omg.CORBA.ORBInitialPort プロパティーに新しいポート番号を設定します。
Java IDL と RMI-IIOP のほとんどのチュートリアルでは、ネームサービス、サーバー、およびクライアントはすべて開発用のマシン上で実行されます。実際に配備する場合には、クライアントとサーバーを、ネームサービスとは異なるホスト上で実行することが多くなります。
クライアントとサーバーがネームサービスを見つけるには、クライアントとサーバーが、ネームサービスが実行されているポートの番号とホストを認識している必要があります。そのためには、クライアントとサーバーのファイル内の org.omg.CORBA.ORBInitialPort プロパティーと org.omg.CORBA.ORBInitialHost プロパティーをネームサービスが実行されているポートの番号とマシンの名前に設定します。この例は、「RMI-IIOP を使った Hello World の例」に示されています。コマンド行オプション -ORBInitialPort nameserverport# と -ORBInitialHost nameserverhostname を使用して、クライアントとサーバーに対してネームサービスを探す場所を指定することもできます。「Java IDL: 2 台のマシン上で実行する Hello World プログラム」には、コマンド行オプションを使用して指定する方法が示されています。
たとえば、一時ネームサービス tnameserv が、ホスト nameserverhost のポート 1050 上で実行されているとします。さらに、クライアントがホスト clienthost 上で実行され、サーバーはホスト serverhost 上で実行されているとします。
tnameserv -ORBInitialPort 1050
java Server -ORBInitialPort 1050 -ORBInitialHost nameserverhost
java Client -ORBInitialPort 1050 -ORBInitialHost nameserverhost
Java IDL ネームサービスを停止するには、Unix の場合は、kill などのオペレーティングシステムのコマンドを使い、Windows の場合は、Ctrl-C を使います。ネームサービスを明示的に停止するまでは、呼び出し待機状態が続きます。なお、サービスを終了させると、Java IDL ネームサービスに登録されている名前は失われます。
次に示すサンプルプログラムは、名前を名前空間に追加する方法を示すものです。このサンプルプログラムは、このままの状態で完全に動作する一時ネームサービスクライアントで、次のような単純なツリーを作成するものです。
この例で、plans はオブジェクト参照、Personal は calendar と schedule の 2 つのオブジェクト参照を含むネーミングコンテキストです。
import java.util.Properties; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class NameClient { public static void main(String args[]) { try {前述の「Java IDL 一時ネームサービスの起動」セクションで、ネームサーバーはポート 1050 を使用して起動しました。次のコードによって、クライアントプログラムはこのポート番号を確実に認識します。
Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); ORB orb = ORB.init(args, props);次のコードでは、初期ネーミングコンテキストを取得し、それを ctx に代入します。2 行目では、ctx をダミーのオブジェクト参照 objref にコピーします。このオブジェクト参照には、あとでさまざまな名前を割り当てて名前空間に追加します。
NamingContext ctx = NamingContextHelper.narrow(orb.resolve_initial_references("NameService")); NamingContext objref = ctx;次のコードでは、text 型の名前 plans を作成し、それをダミーのオブジェクト参照にバインドします。その後、
rebind
を使用して初期ネーミングコンテキストの下に "plans" を追加しています。rebind
メソッドを使用すれば、bind
を使用した場合に発生する例外を発生させずに、このプログラムを何度も繰り返し実行できます。
NameComponent nc1 = new NameComponent("plans", "text"); NameComponent[] name1 = {nc1}; ctx.rebind(name1, objref); System.out.println("plans rebind successful!");次のコードでは、directory 型の Personal というネーミングコンテキストを作成します。その結果得られるオブジェクト参照 ctx2 をこの名前にバインドし、初期ネーミングコンテキストに追加します。
NameComponent nc2 = new NameComponent("Personal", "directory"); NameComponent[] name2 = {nc2}; NamingContext ctx2 = ctx.bind_new_context(name2); System.out.println("new naming context added..");残りのコードでは、ダミーのオブジェクト参照を schedule と calendar という名前でネーミングコンテキスト "Personal" (ctx2) にバインドします。
NameComponent nc3 = new NameComponent("schedule", "text"); NameComponent[] name3 = {nc3}; ctx2.rebind(name3, objref); System.out.println("schedule rebind successful!"); NameComponent nc4 = new NameComponent("calender", "text"); NameComponent[] name4 = {nc4}; ctx2.rebind(name4, objref); System.out.println("calender rebind successful!"); } catch (Exception e) { e.printStackTrace(System.err); } } }
次のサンプルプログラムでは、名前空間をブラウズする方法を示します。
import java.util.Properties; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class NameClientList { public static void main(String args[]) { try {前述の「Java IDL 一時ネームサービスの起動」セクションで、ネームサーバーはポート 1050 を使用して起動しました。次のコードによって、クライアントプログラムはこのポート番号を確実に認識します。
Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); ORB orb = ORB.init(args, props);次のコードでは、初期ネーミングコンテキストを取得しています。
NamingContext nc = NamingContextHelper.narrow(orb.resolve_initial_references("NameService"));
list
メソッドは、ネーミングコンテキストに追加されているバインディングをリストします。この場合、最大 1000 個までのバインディングが初期ネーミングコンテキストから BindingListHolder に返されます。残りのバインディングは、BindingIteratorHolder に返されます。
BindingListHolder bl = new BindingListHolder(); BindingIteratorHolder blIt= new BindingIteratorHolder(); nc.list(1000, bl, blIt);次のコードでは、返された BindingListHolder からバインディングの配列を取得します。バインディングがない場合は、プログラムは終了します。
Binding bindings[] = bl.value; if (bindings.length == 0) return;残りのコードでは、バインディングに対してループ処理を行い、名前を出力します。
for (int i=0; i < bindings.length; i++) { // get the object reference for each binding org.omg.CORBA.Object obj = nc.resolve(bindings[i].binding_name); String objStr = orb.object_to_string(obj); int lastIx = bindings[i].binding_name.length-1; // check to see if this is a naming context if (bindings[i].binding_type == BindingType.ncontext) { System.out.println( "Context: " + bindings[i].binding_name[lastIx].id); } else { System.out.println("Object: " + bindings[i].binding_name[lastIx].id); } } } catch (Exception e) { e.printStackTrace(System.err); } } }