ここでは、次の項目について説明します。
CORBA の COS (Common Object Services) ネームサービスは、ファイルシステムがファイルに対してディレクトリ構造を提供しているのと同じように、オブジェクト参照に対してツリー構造のディレクトリを提供します。Java IDL のネームサービスは、COS ネームサービスの仕様の実装です。次に、このドキュメントから抜粋した概要を示します。
名前とオブジェクトの関連付けは、「ネームバインディング」と呼ばれます。ネームバインディングは、常に「ネーミングコンテキスト」に対して相対的に定義されます。ネーミングコンテキストは、それぞれが一意の名前を持つ一連のネームバインディングを格納するオブジェクトです。異なる名前を、同時に、同じコンテキストまたは異なるコンテキストでバインドできます。
「名前の解決」とは、特定のコンテキスト内でその名前に関連付けられているオブジェクトを判別することです。「名前のバインド」とは、特定のコンテキスト内でネームバインディングを作成することです。名前は、常にコンテキストに対して相対的に解決され、絶対名は存在しません。
コンテキストはほかのオブジェクトと同様に、コンテキスト自体もネーミングコンテキスト内で名前にバインドできます。ほかのコンテキスト内でコンテキストをバインディングすると、「ネーミンググラフ」が作成されます。ネーミンググラフは、ノードとラベルの付いた境界を含む有向グラフで、各コンテキストがノードになります。ネーミンググラフを使用すると、複雑な名前を使ってオブジェクトを参照できるようになります。ネーミンググラフ内のコンテキストが指定された場合、名前のシーケンスでオブジェクトを参照できます。この名前のシーケンス (「複合名」と呼ばれる) は、解決処理をナビゲートするための、ネーミンググラフ内のパスです。
次の図にネーミンググラフの例を示します。名前空間に名前を追加する方法を示すサンプルプログラムでもこれと同じモデルを使用しています。
アプリケーションから COS ネームサービスを使用するためには、その ORB はネームサービスが動作しているホストのポートを知っているか、そのネームサービスの文字列化された初期ネーミングコンテキストにアクセスできなければなりません。ネームサービスは、Java IDL のネームサービスでもその他の COS 準拠のネームサービスでもかまいません。
ORBD は、クライアントまたはサーバーを実行する前に起動します。ORBD には、持続ネームサービスおよび一時ネームサービスが組み込まれています。これらはどちらも COS ネームサービスの実装です。
クライアントとサーバーの両方が、使用するルートネーミングコンテキストについて同意する必要があります。ルートネーミングコンテキストを取得するには、orb.resolve_initial_references(String name_of_service) メソッドを使用します。「NameService」によって提供されるネームサービスのハンドルを name_of_service として取得すると、持続ネームサービスが取得されます。つまり、そのネーミングコンテキストのグラフは、サーバーに障害が発生しても復元されます。「TnameService」を使用してハンドルを取得すると、一時ネームサービスが取得されます。つまり、サービスが中断された場合は、orb.resolve_initial_references(String name_of_service) を使用してルートネーミングコンテキストを再取得する必要があります。
次に例を示します。
// get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
文字列「NameService」は、すべての CORBA ORB に対して定義されています。この文字列を渡すと、ORB は、次のネームサービスのオブジェクト参照であるネーミングコンテキストオブジェクトを返します。
ORBD とともに一時ネームサービスを使用することを指定するには、文字列「TnameService」を渡します。文字列「TnameService」は、固有の名前です。この文字列を渡すと、ORB は、ORBD の一時ネームサービスへのオブジェクト参照であるネーミングコンテキストオブジェクトを返します。
CORBA のすべてのオブジェクト参照と同様に、objRef はジェネリック CORBA オブジェクトです。これを NamingContextExt オブジェクトとして使うには、適切な型にナロー変換する必要があります。
NamingContextExtHelper は、idlj により生成されるヘルパークラスです。このクラスの機能は HelloHelper の機能に類似しています。ここで ncRef オブジェクトは org.omg.CosNaming.NamingContextExt になったので、これを使ってネームサービスにアクセスし、サーバーを登録することができます。
NamingContextExt および NamingContextExtHelper は、J2SE のこのリリースで新しく追加されました。NamingContextExt は、NamingContext を拡張したものです。これは、Interoperable Naming Service の一部であり、各名前が固有になっている一連のネームバインディングを含んでいます。異なる名前を、同時に、同じコンテキストまたは異なるコンテキストでバインドできます。NamingContextExt を使用すると、URL ベースの名前を使用してバインドと解決を行うことができます。NamingContextExtHelper は、narrow() などの、型固有でビジネスロジックを処理しない追加のヘルパーメソッドを提供します。
Interoperable Naming Service (INS) は CORBA ネームサービスの上にある URL ベースのネーミングシステムで、アプリケーションに共通の初期ネーミングコンテキストを共有させる共通のブートストラップメカニズムでもあります。
Interoperable Naming Service (INS) には次の機能があります。
INS の使用方法を示すアプリケーションの例については、Interoperable Naming Service の例を参照してください。
次の図は、INS がどのように ORBD に適合するかを示しています。
オブジェクト参照には、少なくとも、アドレス、オブジェクト参照を作成した POA の名前、およびオブジェクト ID という 3 つの情報が含まれています。
INS を使用すると、文字列化された IOR よりも読みやすい、CORBA オブジェクトにアクセスするための URL を提供できます。次のような文字列化されたオブジェクト参照形式を使用できます。
IOR は、オブジェクト参照であり、OMG によって定義された GIOP プロトコルや IIOP プロトコルを使用して情報をやりとりできる ORB によって認識されます。クライアントは、「名前空間のブラウズ」の例に示すように、orb.object_to_string(objRef) を使用してオブジェクト参照を取得するか、または別のオブジェクト参照の起動の結果として、オブジェクト参照を取得できます。
注: IOR が複数のプロファイルを含んでいる場合、J2SE v1.4 以降の ORB は、常に最初のプロファイルを使用します。
corbaloc:形式は、CORBA クライアントにとって有効な形式で、一般的に、GIOP の LocateRequest メッセージまたは Request メッセージを使用して、参照を解決するために使用されます。たとえば、corbaloc:オブジェクト参照は、次のようになります。
corbaloc:iiop:1.2@example.com:2050/TraderService
この例は、ホスト example.com のポート 2050 から TraderService のオブジェクト参照を取得する方法を示しています。
corbaname: 形式は、クライアントが直接ブートストラップするためのメカニズムを提供するもので、一般的に、ルートネーミングコンテキストの文字列化された名前を解決するために使用されます。たとえば、corbaname: オブジェクト参照は、次のようになります。
corbaname::example.com:2050#Personal/schedule
example.com はホストで、2050 はポートです。ハッシュマークまでの部分の参照 (corbaname::example.com:2050) は、ルートネーミングコンテキストを返す URL です。この例は、a) ネームサービスを探し、b) ネームサービスの Personal/schedule という名前を解決するために使用される URL を示しています。
INS は、ブートストラップ用の ORB オプションを提供します。CORBA システムをブートストラップするには、CORBA システムにオブジェクト参照を渡す必要があります。ORBInitRef または ORBDefaultInitRef を使用すると、resolve_initial_references() からカスタマイズされた CORBA サービスのハンドルを返すように ORB を構成できます。次に例を示します。
-ORBInitRef TraderService=corbaloc::example.com:2050/TraderService -ORBDefaultInitRef corbaloc:iiop:1.2:example.com:2050
これらのオプションを使用した場合、解決の順番は次のようになります。
INS の詳細については、INS ネーミング仕様を参照してください。
ネームサービスを使用するには、初めに、名前空間や名前空間内のオブジェクトを検出または作成するサーバーとクライアントのコードを記述する必要があります。クライアントとサーバーを実行する前に、ネームサービスを起動し、クライアントとサーバーに対してネームサービスを探す場所を指定する必要があります。クライアントとサーバーがネームサービスへのアクセスを試行したときに、実行されるステップの概要を次に示します。
ここでは、次の項目について説明します。
次に示すサンプルプログラムは、名前を名前空間に追加する方法を示すものです。このサンプルプログラムは、このままの状態で完全に動作するネームサービスクライアントで、次のような単純なツリーを作成するものです。ネーミングコンテキストはイタリックフォントで示し、オブジェクト参照は normal
フォントで示します。
この例で、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 {
「ネームサービスの起動」のセクションでは、ネームサーバーは、ホスト localhost のポート 1050 上で起動されます。次のコードによって、クライアントプログラムにこのポート番号とホスト名を認識させます。
Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); props.put("org.omg.CORBA.ORBInitialHost", "localhost"); ORB orb = ORB.init(args, props);
次のコードでは、初期ネーミングコンテキストを取得し、それを ctx に代入します。2 行目では、ctx をダミーのオブジェクト参照 objref にコピーします。このオブジェクト参照には、あとでさまざまな名前を割り当てて名前空間に追加します。
NamingContextExt ctx = NamingContextExtHelper.narrow(orb.resolve_initial_references( "NameService")); org.omg.CORBA.Object objref = ctx;
次のコードでは、名前「plans」をダミーのオブジェクト参照にバインドします。その後、rebind
を使用して初期ネーミングコンテキストの下にオブジェクト参照「plans」を追加しています。rebind
メソッドを使用すれば、bind
を使用した場合に発生する例外を発生させずに、このプログラムを何度も繰り返し実行できます。
NameComponent name1[] = ctx.to_name("plans"); ctx.rebind(name1, objref); System.out.println("plans rebind successful!");
次のコードでは、「Personal」という名前の新しいネーミングコンテキストを作成します。その結果得られるオブジェクト参照 ctx2 をこの名前にバインドし、初期ネーミングコンテキストに追加します。
NameComponent name2[] = ctx.to_name("Personal"); NamingContextExt ctx2 = (NamingContextExt)ctx.bind_new_context(name2); System.out.println("New naming context, Personal, added!");
次のコードでは、ダミーのオブジェクト参照を「schedule」と「calendar」という名前で、ネーミングコンテキスト「Personal」(ctx2) にバインドします。
NameComponent name3[] = ctx.to_name("schedule"); ctx2.rebind(name3, objref); System.out.println("schedule rebind successful!"); NameComponent name4[] = ctx.to_name("calendar"); ctx2.rebind(name4, objref); System.out.println("calendar rebind successful!"); } catch (Exception e) { e.printStackTrace(System.err); } } }
javac NameClient.java
続行する前に構文エラーを修正します。
java NameClient -ORBInitialPort 1050
端末ウィンドウの出力は次のようになります。
これで、ネームサービスに対して上の図のように認識される名前空間が作成できました。
次に示すサンプルプログラムは、名前を名前空間から解決する方法を示すものです。「名前の解決」とは、特定のコンテキスト内でその名前に関連付けられているオブジェクトを判別することです。持続ネームサービスを使用する場合は、ネームサービスが停止したときでも、ふたたび解決する必要はありません。一時ネームサービスを使用する場合は、ネームサービスが停止したときに、ふたたび解決する必要があります。
この例で、plans はオブジェクト参照、Personal は calendar と schedule の 2 つのオブジェクト参照を含むネーミングコンテキストです。
import java.util.Properties; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class NameClientResolve { public static void main(String args[]) { try {
「ネームサービスの起動」のセクションでは、ネームサーバーは、ホスト localhost のポート 1050 上で起動されます。次のコードによって、クライアントプログラムにこのポート番号とホスト名を認識させます。
Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); props.put("org.omg.CORBA.ORBInitialHost", "localhost"); ORB orb = ORB.init(args, props);
次のコードでは、初期ネーミングコンテキストを取得し、それを nc に代入します。
NamingContextExt nc = NamingContextExtHelper.narrow(orb.resolve_initial_references( "NameService"));
次のコードでは、各名前空間を解決します。
org.omg.CORBA.Object sched = nc.resolve_str("Personal/schedule"); org.omg.CORBA.Object cal = nc.resolve_str("Personal/calendar"); org.omg.CORBA.Object plan = nc.resolve_str("plans"); //finish the try-catch block } catch (Exception e) { e.printStackTrace(System.err); } }
javac NameClientResolve.java
続行する前に構文エラーを修正します。
java NameClientResolve -ORBInitialPort 1050
このクライアントアプリケーションを実行したときに端末ウィンドウには何も表示されません。オブジェクト参照が解決されたことを確認する必要がある場合は、次のようなテスト用のコードを追加します。
if (sched == null){ System.out.println("Schedule is null"); } if (cal == null){ System.out.println("Calendar is null"); } if (plan == null){ System.out.println("Plans is null"); }
次のサンプルプログラムでは、名前空間をブラウズする方法を示します。
import java.util.Properties; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class NameClientList { public static void main(String args[]) { try {
「ネームサービスの起動」のセクションでは、ネームサーバーは、ホスト localhost のポート 1050 上で起動されます。次のコードによって、クライアントプログラムにこのポート番号とホスト名を認識させます。
Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort", "1050"); props.put("org.omg.CORBA.ORBInitialHost", "localhost"); ORB orb = ORB.init(args, props);
NamingContextExt nc = NamingContextExtHelper.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;
for (int i=0; i < bindings.length; i++) { 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); } } }
javac NameClientList.java
続行する前に構文エラーを修正します。
java NameClientList -ORBInitialPort 1050
端末ウィンドウの出力は次のようになります。
orbd
) を使用します。これには、持続ネームサービスと一時ネームサービスの両方が組み込まれており、J2SE 1.4 以降をダウンロードすれば入手できます。
呼び出し側 (クライアント、ピア、またはクライアントアプリケーション) がリモートオブジェクトのメソッドを呼び出すには、呼び出し側はまずリモートオブジェクトへの参照を取得する必要があります。
リモートオブジェクトがサーバーに登録されると、呼び出し側は、そのオブジェクトを名前によって検索して、リモートオブジェクトへの参照を取得できます。そうすれば、そのオブジェクトのメソッドをリモートから呼び出せます。
これにより、そのオブジェクトのメソッドをリモートから呼び出せます。ネームサービスの起動方法については、ORBD ドキュメントの「ネームサービスの起動」を参照してください。
ネームサービスを停止するには、適切なオペレーティングシステムコマンドを使用します。たとえば、Solaris では kill を使用し、orbd が実行されている DOS ウィンドウでは Ctrl+C キーを使用します。一時ネームサービスの場合は、サービスが終了されると、ネームサービスに登録された名前が消去される場合があります。Java IDL ネームサービスは、明示的に停止されるまで実行されます。
Sun ORB をほかのベンダーのネームサービスとともに使用するには
-ORBInitRef NameService=corbaloc:iiop:1.2@<H>:<P>/NameService
orb.resolve_initial_references("NameService") を実行すると、サードパーティー製のネームサービスに接続できるようになるはずです。接続できない場合は、次のトラブルシューティングに関するヒントを試してください。