ネーム・サービス

ここでは、次の項目について説明します。

COSネーム・サービス: 概要

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

Interoperable Naming Service (INS)はCORBAネーム・サービスの上にあるURLベースのネーミング・システムで、アプリケーションに共通の初期ネーミング・コンテキストを共有させる共通のブートストラップ・メカニズムでもあります。

Interoperable Naming Service (INS)には次の機能があります。

INSの使用方法を示すアプリケーションの例については、Interoperable Naming Serviceの例を参照してください。

次の図は、INSがどのようにORBDに適合するかを示しています。

ORBD



オブジェクト参照には、少なくとも、アドレス、オブジェクト参照を作成したPOAの名前、およびオブジェクトIDという3つの情報が含まれています。

INSを使用すると、文字列化されたIORよりも読みやすい、CORBAオブジェクトにアクセスするためのURLを提供できます。次のような文字列化されたオブジェクト参照形式を使用できます。

ORBのブートストラップ・オプション

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

これらのオプションを使用した場合、解決の順番は次のようになります。

  1. register_initial_referencesに登録されたオブジェクト
  2. -ORBInitRef
  3. -ORBDefaultInitRef
  4. 独自のブートストラップ(Sun ORBのみ)

INSの詳細については、INSネーミング仕様を参照してください。

ネーム・サービスの使用

ネーム・サービスを使用するには、初めに、名前空間や名前空間内のオブジェクトを検出または作成するサーバーとクライアントのコードを記述する必要があります。クライアントとサーバーを実行する前に、ネーム・サービスを起動し、クライアントとサーバーに対してネーム・サービスを探す場所を指定する必要があります。クライアントとサーバーがネーム・サービスへのアクセスを試行したときに、実行されるステップの概要を次に示します。

ここでは、次の項目について説明します。

サンプル・クライアント: 名前空間へのオブジェクトの追加

次に示すサンプル・プログラムは、名前を名前空間に追加する方法を示すものです。これは自己完結型のネーム・サービス・クライアントで、次のような単純なツリーを作成するものです。ネーミング・コンテキストはイタリック・フォントで示し、オブジェクト参照はnormalフォントで示します。

名前空間への名前の追加

この例で、plansはオブジェクト参照、Personalcalendarscheduleの2つのオブジェクト参照を含むネーミング・コンテキストです。

  1. NameClient.javaファイルを作成し、適切なライブラリをインポートします。
    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClient
    {
       public static void main(String args[])
       {
          try {
    
  2. ポートとホストのプロパティを設定します。

    ネーム・サービスの起動」のセクションでは、ネーム・サーバーは、ホスト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);
    
  3. 初期ネーミング・コンテキストを取得します。

    次のコードでは、初期ネーミング・コンテキストを取得し、それをctxに代入します。2行目では、ctxをダミーのオブジェクト参照objrefにコピーします。このオブジェクト参照には、後で様々な名前を割り当てて名前空間に追加します。

     
            NamingContextExt ctx =
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
            org.omg.CORBA.Object objref = ctx;
    
  4. 名前「plans」をオブジェクト参照にバインドします。

    次のコードでは、名前「plans」をダミーのオブジェクト参照にバインドします。その後、rebindを使用して初期ネーミング・コンテキストの下にオブジェクト参照「plans」を追加しています。rebindメソッドを使用すれば、bindを使用した場合に発生する例外を発生させずに、このプログラムを何度も繰返し実行できます。

            NameComponent name1[] = ctx.to_name("plans");
            ctx.rebind(name1, objref);
            System.out.println("plans rebind successful!");
    
  5. 「Personal」という名前の新しいネーミング・コンテキストを作成します。

    次のコードでは、「Personal」という名前の新しいネーミング・コンテキストを作成します。その結果得られるオブジェクト参照ctx2をこの名前にバインドし、初期ネーミング・コンテキストに追加します。

            NameComponent name2[] = ctx.to_name("Personal");
            NamingContextExt ctx2 = (NamingContextExt)ctx.bind_new_context(name2);
            System.out.println("New naming context, Personal, added!");
    
  6. 「schedule」と「calendar」をダミーのオブジェクト参照にバインドします。「名前のバインド」とは、特定のコンテキスト内でネーム・バインディングを作成することです。名前は、常にコンテキストに対して相対的に解決され、絶対名は存在しません。

    次のコードでは、ダミーのオブジェクト参照を「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);
        }
      }  
    }
    
  7. NameClient.javaを保存し、次のようにそのファイルをコンパイルします。
         javac NameClient.java
    

    続行する前に構文エラーを修正します。

  8. ネーム・サービスの起動」に示す手順に従ってObject Request Broker Daemonを実行します。
  9. 次のようにNameClientを実行します。
         java NameClient -ORBInitialPort 1050
    

端末ウィンドウの出力は次のようになります。

端末ウィンドウの出力

これで、ネーム・サービスに対して上の図のように認識される名前空間が作成できました。

サンプル・クライアント: 名前空間からのオブジェクトの解決

次に示すサンプル・プログラムは、名前を名前空間から解決する方法を示すものです。「名前の解決」とは、特定のコンテキスト内でその名前に関連付けられているオブジェクトを判別することです。持続ネーム・サービスを使用する場合は、ネーム・サービスが停止したときでも、ふたたび解決する必要はありません。一時ネーム・サービスを使用する場合は、ネーム・サービスが停止したときに、ふたたび解決する必要があります。

この例で、plansはオブジェクト参照、Personalcalendarscheduleの2つのオブジェクト参照を含むネーミング・コンテキストです。

  1. NameClientResolve.javaファイルを作成し、適切なライブラリをインポートします。
    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClientResolve
    {
       public static void main(String args[])
       {
          try {
    
  2. ポートとホストのプロパティを設定します。

    ネーム・サービスの起動」のセクションでは、ネーム・サーバーは、ホスト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);
    
    
  3. 初期ネーミング・コンテキストを取得します。

    次のコードでは、初期ネーミング・コンテキストを取得し、それをncに代入します。

     
            NamingContextExt nc =
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
    
  4. 各名前空間を解決します。

    次のコードでは、各名前空間を解決します。

       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);
            } 
    }
    
  5. NameClientResolve.javaを保存し、次のようにそのファイルをコンパイルします。
         javac NameClientResolve.java
    

    続行する前に構文エラーを修正します。

  6. Object Request Broker Daemonが実行され、「サンプル・クライアント: 名前空間へのオブジェクトの追加」で説明したクライアント・アプリケーションが実行されていることを確認します。
  7. 次のようにNameClientResolveを実行します。
         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");
        }

サンプル・クライアント: 名前空間のブラウズ

次のサンプル・プログラムでは、名前空間をブラウズする方法を示します。

  1. NameClientList.javaファイルを作成し、適切なライブラリをインポートします。
    import java.util.Properties;
    import org.omg.CORBA.*;
    import org.omg.CosNaming.*;
    
    public class NameClientList
    {
       public static void main(String args[])
       {
          try {
    
  2. ネーム・サービスの起動」のセクションでは、ネーム・サーバーは、ホスト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);
    
    
    
  3. 初期ネーミング・コンテキストを取得します。
            NamingContextExt nc = 
              NamingContextExtHelper.narrow(orb.resolve_initial_references(
                "NameService"));
    
    
  4. ネーミング・コンテキスト内のすべてのバインディングを一覧表示します。

    listメソッドは、ネーミング・コンテキストに追加されているバインディングをリストします。この場合、最大1000個までのバインディングが初期ネーミング・コンテキストからBindingListHolderに返されます。残りのバインディングは、BindingIteratorHolderに返されます。

     
            BindingListHolder bl = new BindingListHolder();
            BindingIteratorHolder blIt= new BindingIteratorHolder();
            nc.list(1000, bl, blIt);
    
    
  5. バインディングの配列を取得します。

    次のコードでは、返されたBindingListHolderからバインディングの配列を取得します。

            Binding bindings[] = bl.value;
    
    
    
  6. 次のコードでは、バインディングに対してループ処理を行い、名前を出力します。
            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);
           } 
       }
    }
    
  7. NameClientList.javaを保存し、次のようにそのファイルをコンパイルします。
         javac NameClientList.java
    

    続行する前に構文エラーを修正します。

  8. Object Request Broker Daemonが実行され、「サンプル・クライアント: 名前空間へのオブジェクトの追加」で説明したクライアント・アプリケーションと、「サンプル・クライアント: 名前空間からのオブジェクトの解決」で説明したクライアント・アプリケーションが実行されていることを確認します。
  9. 次のようにNameClientListを実行します。
         java NameClientList -ORBInitialPort 1050
    

端末ウィンドウの出力は次のようになります。

端末ウィンドウの出力

ネーム・サービスの起動

すべてのチュートリアルで、Object Request Broker Daemon (orbd)を使用します。これには、持続ネーム・サービスと一時ネーム・サービスの両方が組み込まれており、J2SE 1.4以降をダウンロードすれば入手できます。

呼出し側(クライアント、ピア、またはクライアント・アプリケーション)がリモート・オブジェクトのメソッドを呼び出すには、呼出し側はまずリモート・オブジェクトへの参照を取得する必要があります。

リモート・オブジェクトがサーバーに登録されると、呼出し側は、そのオブジェクトを名前によって検索して、リモート・オブジェクトへの参照を取得できます。そうすれば、そのオブジェクトのメソッドをリモートから呼び出せます。

ネーム・サービスの起動方法については、orbdのマニュアル・ページ (Solaris、Linux、Mac OS XまたはWindows)を参照してください。

ネーム・サービスの停止

ネーム・サービスを停止するには、適切なオペレーティング・システム・コマンドを使用します。たとえば、Solarisではkillを使用し、orbdが実行されているDOSウィンドウではCtrl+Cキーを使用します。一時ネーム・サービスの場合は、サービスが終了されると、ネーム・サービスに登録された名前が消去される場合があります。Java IDLネーム・サービスは、明示的に停止されるまで実行されます。

ネーム・サービスのFAQ

SunのORBからサード・パーティ製のネーム・サービスに接続する方法を教えてください。

サード・パーティ製のネーム・サービスが、Interoperable Naming Service (INS)をサポートしている場合は、INSオプションを使用する方法をお薦めします。

Sun ORBをほかのベンダーのネーム・サービスとともに使用するには

  1. ホスト<H>およびポート<P>上でサード・パーティ製のネーム・サーバーを起動します。
  2. 次の引数をORB.init()に渡します。
            -ORBInitRef NameService=corbaloc:iiop:1.2@<H>:<P>/NameService
            
    

orb.resolve_initial_references("NameService")を実行すると、サード・パーティ製のネーム・サービスに接続できるようになるはずです。接続できない場合は、次のトラブルシューティングに関するヒントを試してください。


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