目次|| Java Management Extensions (JMX)テクノロジのチュートリアル

第4章

検索サービス

Java Management Extension (JMX)仕様では、次のセクションで説明する既存の検索テクノロジを使用した、検索サービスの3つのバインディングを定義しています。

検索サービスを使用すると、JMXテクノロジのクライアントは、検索サービスに登録されているコネクタ・サーバーを検索し、接続することができます。

初期設定

セクション「RMIコネクタを使用した標準および動的MBeanへのアクセス」で簡単に示したように、リモート・メソッド呼び出し(RMI)コネクタを使用している場合、検索するコネクタ・サーバー・スタブの登録に外部ディレクトリを使用することができます。RMIコネクタに関連した検索サービスの例の中で、次のケースを示します。

  • 次の外部ディレクトリのいずれかを使用したRMIコネクタ
  • RMIレジストリ。デフォルトのJava Remote Method Protocol (JRMP)トランスポートを実装するRMIコネクタ向け
  • CORBAネーム・サービス。Internet Inter-ORB Protocol (IIOP)トランスポートを実装するRMIコネクタ向け
  • Lightweight Directory Access Protocol (LDAP)。IIOPとJRMPの両トランスポート向け
  • 外部ディレクトリを使用しないRMIコネクタ

外部ディレクトリにRMIコネクタ・スタブを登録する場合、RMIレジストリ、CORBAネーム・サービス、またはLDAPサーバーの構成のための初期設定が必要になります。外部ディレクトリを使用しない場合、RMIコネクタ・スタブはJMXサービスURLにエンコードされます。

次のセクションでは、RMIコネクタを使用する検索サービスの例に使用できる外部ディレクトリについて説明します。これらの外部ディレクトリは、この章の以降のセクションで示す検索サービスの3つの例を実行する場合に参照されます。

外部RMIレジストリ

JRMPトランスポートを実装するコネクタで使用するために、外部RMIレジストリにRMIコネクタ・サーバー・スタブを登録するには、次の手順を実行します。

  1. ローカル・ホストのポート9999でRMIレジストリを起動します。

    第3章「JMXコネクタ」の例と同様に、RMIレジストリはJRMPトランスポートを実装するRMIコネクタ用のRMIコネクタ・スタブを格納するために使用されます。

    $ rmiregistry 9999 &

  2. コマンドを入力する場合、RMIレジストリのアドレスに環境変数を作成すると便利です。

    例を実行するときに入力するコマンドを短くするために、RMIレジストリのサービスURLを環境変数jndirmiとして設定します。次の例では、サービスURLはJNDI形式で指定されています。JNDI形式の詳細は、javax.management.remote.rmiパッケージのAPIドキュメントを参照してください。ローカル・マシン以外のマシンで外部ディレクトリを実行する場合は、ローカル・ホストの代わりに、そのマシンのホスト名を指定する必要があります。

    $ jndirmi="rmi://localhost:9999"

外部CORBAネーム・サービス

IIOPトランスポートを実装するコネクタで使用するために、外部CORBAネーム・サービスにRMIコネクタ・サーバー・スタブを登録するには、次の手順を実行します。

  1. ローカル・ホストのポート7777で、Object Request Broker (ORB)デーモンを起動します。

    IIOPトランスポートを実装するRMIコネクタは、CORBAネームを使用してRMIコネクタ・スタブを識別できます。

    $ orbd -ORBInitialPort 7777 &

  2. コマンドを入力する場合に備えて、CORBAネーム・サービスのアドレスに環境変数を作成します。

    例を実行するときに入力するコマンドを短くするために、CORBAネーム・サービスのサービスURLを環境変数jndiiiopとして設定します。次の例では、サービスURLはJNDI形式で指定されています。ローカル・マシン以外のマシンで外部ディレクトリを実行する場合は、ローカル・ホストの代わりに、そのマシンのホスト名を指定する必要があります。

    $ jndiiiop="iiop://localhost:7777"

外部LDAPレジストリ

JRMPまたはIIOPトランスポートのいずれかを実装するコネクタで使用するために、外部LDAPレジストリにRMIコネクタ・サーバー・スタブを登録するには、次の手順を実行します。

  1. LDAPサーバーを起動します。

    使用するLDAPサーバーは選択できますが、LDAPディレクトリでJavaオブジェクトを表すためのスキーマがサーバーに認識されている必要があります。詳細は、関連するRequest For Comments (RFC)ドキュメントを参照してください。

    http://www.ietf.org/rfc/rfc2713.txt

  2. ドメイン・コンポーネントのサフィックスを作成します。

    次の例では、次のドメイン・コンポーネントのサフィックスの作成が必要になります。

    dc=Test

    サーバーの構成方法と、このサフィックスの作成方法の詳細は、使用しているLDAPサーバーに付属のドキュメントを参照してください。

  3. 便宜上、環境変数に次のLDAPパラメータを設定します。

    これらの変数は、外部LDAPサーバーにRMIコネクタ・スタブを登録する検索サービスの例で、ServerクラスとClientクラスを起動するときに、入力するコマンドを短縮するために使用します。

    1. LDAPサーバーを実行するマシンの名前(ldap_host)

      $ ldaphost=ldap_host

    2. LDAPサーバーが稼動するポート(ldap_port)

      $ ldapport=ldap_port

    3. LDAPコマンド名属性。次の例では「Directory Manager」

      $ principal=”cn=Directory Manager”

    4. LDAPサーバーで要求されるパスワード

      LDAPサーバーのパスワードを指定します。

      $ credentials=your_ldap_password

    5. LDAPサーバーのアドレス

      この例では、LDAPサーバーのサービスURLはJNDI形式で指定され、変数jndildapで識別されます。

      $ jndildap="ldap://$ldaphost:$ldapport"

    • これで、各種の検索サービスの例を実行する準備ができました。

Service Location Protocol (SLP)検索サービス

JMXテクノロジの仕様では、SLP検索サービスにRMIコネクタを登録する方法が指定されています。

この例の目的は、JMX Remote APIコネクタ・クライアントで、SLP検索サービスに登録されたコネクタ・サーバーを検索し、接続する方法を示すことです。この例では、次の操作を実行します。

  • エージェント側:
  • MBeanサーバーを作成
  • SLP検索サービスのポインタを取得
  • コネクタ・サーバーを作成
  • SLP検索サービスにコネクタ・アドレスを登録
  • クライアント側:
  • SLP検索サービスのポインタを取得
  • SLP検索サービスに登録されたすべてのコネクタ・サーバーを検索
  • JMX Remote APIコネクタを作成
  • MBeanサーバーのMBeanに関する情報を取得

この例は、ユーザーがSLPテクノロジに習熟していることを前提に記載されています。この例に示すコードは、RFC 2614 (http://www.ietf.org/rfc/rfc2614.txtを参照)で定義されているSun MicrosystemsのSLPの実装に準拠しています。Sun MicrosystemsのSLPの実装は、ディレクトリ/usr/share/lib/slpのSolarisオペレーティング環境で使用できます。Solarisオペレーティング環境を実行していない場合は、「RFC 2614、Section 5」に準拠したバージョンのSLPを入手する必要があります。OpenSLP Java実装は、http://www.openslp.org/からダウンロードできます。

SLP検索の例は、ディレクトリwork_dir/jmx_examples/Lookup/slp内にあります。

  1. work_dir/jmx_examples/Lookup/slpを開きます。

    このディレクトリ内には、次のファイルがあります。

    • Server.java
    • Client.java
    • README
  2. テキスト・エディタで2つの*.javaファイルを開きます。

    これらのクラスについて、以降のセクションで分析します。

例題クラスの分析

次のセクションでは、SLP検索の例題で使用される各クラスを分析し、各クラスが上記で説明した操作をどのように実行するかについて説明します。


注 - Sun Microsystemsの実装以外のSLPの実装を使用している場合は、com.sun.slpパッケージの代わりに使用しているバージョンのSLP Javaクラスをインポートするため、Server.javaClient.javaを変更する必要があります。RFC 2614、Section 5を参照してください。

Server.java

SLP検索サービスのServer.javaクラスは、その大きさにより、いくつかのコード(抜粋)で示されます。この例で使用されるSLPコードの詳細は、RFC 2614とSLPのAPIドキュメントを参照してください。

コード例4-1 SLP検索サービスの例クラスServer.java (抜粋1)
 
public class Server { 
   public final static int JMX_DEFAULT_LEASE = 300; 
   public final static String JMX_SCOPE = "DEFAULT"; 
 
   private final MBeanServer mbs; 
   public Server() { 
       mbs = MBeanServerFactory.createMBeanServer(); 
   } 
    
[...] 
 

コード例4-1では、デフォルトのSLPリースJMX_DEFAULT_LEASEを、URLの登録期間に対応するデフォルト・リース300秒に設定し、MBeanサーバーmbsの初期作成を行なっています。

上記のコードでは示していませんが、次にSLPアドバタイザslpAdvertiserとSLPサービスURL urlを定義します。slpAdvertiserは、SLP検索サービスにサービスURLを登録する場合に使用します。SCOPEagentNameは、SLPに検索属性として登録されます。

コード例4-2 SLP検索サービスの例クラスServer.java (抜粋2)
 
[...] 
 
   public static void register(JMXServiceURL jmxUrl, String name) 
     throws ServiceLocationException { 
     ServiceURL serviceURL = 
          new ServiceURL(jmxUrl.toString(), 
                         JMX_DEFAULT_LEASE); 
     debug("ServiceType is: " + serviceURL.getServiceType()); 
     Vector attributes = new Vector(); 
     Vector attrValues = new Vector(); 
     attrValues.add(JMX_SCOPE); 
     ServiceLocationAttribute attr1 = 
          new ServiceLocationAttribute("SCOPE", attrValues); 
     attributes.add(attr1); 
     attrValues.removeAllElements(); 
     attrValues.add(name); 
     ServiceLocationAttribute attr2 = 
          new ServiceLocationAttribute("AgentName", attrValues); 
     attributes.add(attr2); 
     final Advertiser slpAdvertiser = 
          ServiceLocationManager.getAdvertiser(Locale.US); 
     slpAdvertiser.register(serviceURL, attributes); 
      
   }  
 
[...] 
 

コード例4-2に、JMXコネクタ・サーバーのURLのSLP検索サービスへの登録を示します。

JMXサービスURL、jmxUrlは、コネクタ・サーバーのアドレスであり、コネクタ・サーバーの起動時にJMXConnectorServergetAddress()メソッドを呼び出して取得します。

このとき、スコープやコネクタ・サーバー・アドレスが登録される際のエージェント名(name)などのSLP検索の属性は、SLPクラスServiceLocationAttributeにより指定されます。AgentName属性は必須ですが、ProtocolTypeAgentHost、およびPropertyなどのほかのオプション属性もSLP検索サービスに登録できます。

最後に、JMXコネクタ・サーバー・アドレスはAdvertiserインタフェースのregister()メソッドの呼出しによりSLPサービスに登録され、パラメータとしてserviceURLattributesが渡されます。

コード例4-3 SLP検索サービスの例クラスServer.java (抜粋3)
 
[...] 
 
   public JMXConnectorServer rmi(String url) throws 
     IOException, 
     JMException, 
     NamingException, 
     ClassNotFoundException, 
     ServiceLocationException { 
     JMXServiceURL jurl = new JMXServiceURL(url); 
     final HashMap env = new HashMap(); 
     // Environment map attributes 
     [...] 
 
  
     JMXConnectorServer rmis = 
        JMXConnectorServerFactory.newJMXConnectorServer(jurl, env, mbs); 
     final String agentName = System.getProperty("agent.name", 
                                                 "DefaultAgent"); 
     start(rmis, agentName); 
 
     return rmis; 
  } 
[...] 
 

コード例4-3に、RMIコネクタ・サーバーの作成を示します。JMXサービスURL jurlは、コマンド行でServerを起動するためのコマンドに含まれる文字列urlから構築されます。RMIコネクタ・サーバー、rmisは、環境マップとアドレスjurlで定義されるシステム・プロパティから作成されます。

次にコネクタ・サーバーが起動し、RMIコネクタ・サーバー・アドレスがagentNameの名前でSLP検索サービスに登録されます。

コード例4-4 SLP検索サービスの例クラスServer.java (抜粋4)
 
[...] 
 
   public void start(JMXConnectorServer server, String agentName) 
      throws IOException, ServiceLocationException { 
      server.start(); 
      final JMXServiceURL address = server.getAddress(); 
      register(address,agentName); 
   } 
    
[...] 
 

コード例4-4に、コネクタ・サーバーserverの起動と、指定されたアドレスaddressを使用したserverのSLP検索サービスへの登録を示します。

Client.java

SLP検索サービスのClient.javaクラスを、コード例4-1、コード例4-2、およびコード例4-3に示します。

コード例4-1 SLP検索サービスの例クラスClient.java (抜粋1)
 
public class Client { 
 
    public final static String JMX_SCOPE = "DEFAULT"; 
 
    public static Locator getLocator() throws ServiceLocationException { 
      final Locator slpLocator = 
          ServiceLocationManager.getLocator(Locale.US); 
      return slpLocator; 
    } 
     
      public static List lookup(Locator slpLocator, String name) 
          throws IOException, ServiceLocationException { 
 
   
          final ArrayList list = new ArrayList(); 
          Vector scopes = new Vector(); 
 
          scopes.add(JMX_SCOPE); 
          String query =  
              "(&(AgentName=" + ((name!=null)?name:"*") + "))"; 
 
          ServiceLocationEnumeration result = 
              slpLocator.findServices(new ServiceType("service:jmx"), 
                                      scopes, query); 
 
          while(result.hasMoreElements()) { 
                final ServiceURL surl = (ServiceURL) result.next(); 
                 
 
             JMXServiceURL jmxUrl = new JMXServiceURL(surl.toString()); 
             try { 
                  JMXConnector client = 
                     JMXConnectorFactory.newJMXConnector(jmxUrl,null); 
                  if (client != null) list.add(client); 
             } catch (IOException x ) {  
             [...] 
             } 
          } 
      } 
      return list; 
    } 
 

コード例4-1ではまず、SLPクラスServiceLocationManagergetLocatorメソッドを呼び出して、SLPサービスLocatorを取得します。次にClientは、特定のエージェント名または特定のパターンに一致するエージェント名でSLPサービスに登録された、すべてのコネクタ・サーバーを取得します。Clientの起動時にエージェント名が指定されていない場合、すべてのエージェント名が考慮されます。

JMXテクノロジ・サービスURL、jmxUrlは、SLPで取得されたエージェントごとに生成されます。各エージェントのSLPサービスURL、surlはパラメータとしてJMXServiceURLインスタンスに渡されます。URL jmxUrlは、JMXConnectorFactorynewJMXConnector()メソッドに渡され、SLPサービスに登録される各エージェントに新しいコネクタ・クライアントclientが作成されます。

取得されたコネクタ・クライアントは、配列リストlistに保存されます。

コード例4-2 SLP検索サービスの例クラスClient.java (抜粋2)
 
public static void listMBeans(MBeanServerConnection server) 
     throws IOException { 
 
     final Set names = server.queryNames(null,null); 
     for (final Iterator i=names.iterator(); i.hasNext(); ) { 
          ObjectName name = (ObjectName)i.next(); 
          System.out.println("Got MBean: "+name); 
          try { 
               MBeanInfo info = 
                  server.getMBeanInfo((ObjectName)name); 
               MBeanAttributeInfo[] attrs = info.getAttributes(); 
               if (attrs == null) continue; 
               for (int j=0; j<attrs.length; j++) { 
                    try { 
                         Object o = 
                         server.getAttribute(name,attrs[j].getName()); 
                         System.out.println("\t\t" + attrs[j].getName() + 
                         " = "+o); 
                    } catch (Exception x) { 
                         System.err.println("JmxClient failed to get " + 
                                             attrs[j].getName() + x); 
                         x.printStackTrace(System.err); 
                    } 
     } 
} 
 

コード例4-2では、SLPサービスに保存されたコネクタ・サーバー・アドレスを使って作成されたすべてのコネクタ・クライアントに、MBeanServerConnectionの参照が取得されています。すべてのMBeanとその属性のリストが取得されます。

コード例4-3 SLP検索サービスの例クラスClient.java (抜粋3)
 
public static void main(String[] args) { 
      try { 
           final String agentName = System.getProperty("agent.name"); 
           final Locator slpLocator = getLocator(); 
           List l = lookup(slpLocator,agentName); 
           int j = 1; 
           for (Iterator i=l.iterator();i.hasNext();j++) { 
                JMXConnector c1 = (JMXConnector) i.next(); 
                if (c1 != null) { 
                    try { 
                         c1.connect(env); 
                    } catch (IOException x) { 
                         System.err.println ("Connection failed: " + x); 
                         x.printStackTrace(System.err); 
                         continue; 
                    } 
 
                    MBeanServerConnection conn = 
                         c1.getMBeanServerConnection(); 
 
                    try { 
                         listMBeans(conn); 
                    } catch (IOException x) { 
                         x.printStackTrace(System.err); 
                    } 
                    try { 
                         c1.close(); 
                    } catch (IOException x) { 
                         x.printStackTrace(System.err); 
                    } 
                } 
           } 
      } catch (Exception x) { 
           x.printStackTrace(System.err); 
      } 
} 
 

コード例4-3では、agent.nameプロパティはSystemクラスのgetProperty()メソッドを呼び出して取得され、SLP検索サービスはLocatorgetLocator()メソッドを呼び出して検索されます。

agentNameの名前を持つすべてのエージェントが検索され、検出されたエージェントへの接続が設定されます。エージェントが指定されていない場合、すべてのエージェントが検索されます。Serverで作成されたMBeanサーバーへの接続が設定され、接続が切断される前に、接続内のすべてのMBeanがリストされます。

SLP検索サービスの例題の実行

SLPを使用する検索サービスの例題を実行するには、セクション「初期設定」で実行した作業のほかにも、この例題に固有の初期作業を事前に実行する必要があります。この作業後、SLPをJMXテクノロジでサポートされる2つのコネクタとともに使用してコネクタの検索を開始できます。

例題を実行する場合、作成されたエージェントの種類と、エージェントの作成に使用されたトランスポートを追跡するために、対応するセクションの文字列に等しい文字サフィックスがエージェント名に含まれています。たとえば、セクションa「外部ディレクトリを使用しないJRMP上のRMIコネクタ」のエージェントはexample-server-aと呼ばれます。

SLP検索サービスの例題の設定

次の手順は、この例題で実行できるすべてのトランスポートで要求されます。

  1. クラスのコンパイルおよび実行が容易になるように、追加で環境変数を定義します。

    セクション「初期設定」で設定された共通の環境変数のほかに、SLPサービスのパスを追加する必要があります。Solarisオペレーティング環境を使用している場合は、次の変数を追加します。

    $ SLPLIB=/usr/share/lib/slp

    別のプラットフォームを使用している場合は、使用しているプラットフォームに合わせてSLPLIBを設定します。

  2. classp環境変数を定義し、エクスポートします。

    この例では、SLPのJavaアーカイブ(JAR)ファイルを含むクラス・パスが必要です。

    $ classp=$SLPLIB/slp.jar

  3. ClientクラスとServerクラスの例題をコンパイルします。

    次のコマンドを入力します。

    $ javac -d .-classpath $classp Server.java Client.java

  4. SLPデーモンを起動します。

    Solarisオペレーティング環境を使用している場合、次のコマンドを入力しますが、これにはスーパー・ユーザー・パスワードが必要です。

    $ su root -c "java -cp $SLPLIB/slpd.jar com.sun.slp.slpd &"

    Password: [type superuser password]

    Solarisシステムを実行していない場合、使用しているSLPの実装に従ってSLPデーモンを起動します。

SLP検索サービスの例題の実行

この例では、SLP検索サービスを使用して、RMIのデフォルトのトランスポートであるJRMP、およびIIOPトランスポートを使用するRMIコネクタ・サーバーを検索する方法を示します。そのほか、セクション「初期設定」で説明したように、RMIコネクタ・スタブの登録には別の外部ディレクトリが使用されています。

ここに示すトランスポートと外部ディレクトリの組み合わせは次のとおりです。

  • 次のものを使用した、JRMPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • RMIレジストリ
  • LDAPレジストリ
  • 次のものを使用した、IIOPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • CORBAネーム・サービス
  • LDAPレジストリ

次の手順に従って例題を実行します。

  1. Serverを起動します。

    Serverの起動に使用するコマンドは、使用している外部ディレクトリによって異なります。Clientを起動する前に、各種のトランスポートおよび外部レジストリを使用して、Serverの次のインスタンスの1つまたは複数を起動できます。

    1. 外部ディレクトリを使用しないJRMP上のRMIコネクタ

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-a \ 
        -Durl ="service:jmx:rmi://" \ 
        slp.Server & 
       
      

      このコマンドで、

      • debugはtrueに設定され、Serverの実行時の画面出力をより詳細なものにします
      • 作成されるエージェントの名前はexample-server-aです
      • サービスURLにより、RMIのデフォルト・トランスポートJRMP上で動作するRMIコネクタの選択が指定されます。

      サーバーが起動すると、RMIコネクタの作成、およびそのURLのSLPサービスへの登録を確認するメッセージが表示されます。

    2. JRMP上のRMIコネクタ。外部ディレクトリにRMIレジストリを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-b \ 
        -Durl="service:jmx:rmi:///jndi/${jndirmi}/server" \ 
        slp.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-bです
      • サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」でjndirmiと特定したRMIレジストリです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLのSLPサービスへの登録を確認するメッセージが表示されます。

    3. JRMP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-c \ 
        -Durl="service:jmx:rmi:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        slp.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-cです
      • サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブが保存される外部ディレクトリは、セクション「初期設定」jndildapと特定したLDAPサーバーです。
      • スタブはLDAPサーバーのTestドメイン・コンポーネントに登録されます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-cでSLPサービスに登録されることの確認が表示されます。

    4. 外部ディレクトリを使用しないIIOP上のRMIコネクタ。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-d \ 
        -Durl="service:jmx:iiop://" \ 
        slp.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-dです
      • サービスURLは、IIOP上のRMIコネクタとして選択されるコネクタを指定します。

      Serverが起動すると、RMIコネクタの作成、および自動的に生成されたURLのSLPサービスへの登録を確認するメッセージが表示されます。

    5. IIOP上のRMIコネクタ。外部ディレクトリにCORBAを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-e \ 
        -Durl="service:jmx:iiop:///jndi/${jndiiiop}/server" \ 
        slp.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-eです
      • サービスURLは、IIOP上のRMIコネクタとして選択されるコネクタを指定します。RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」jndiiiopと特定したCORBAネーム・サービスです

      Serverが起動すると、RMIコネクタの作成、およびそのURLがexample-server-eの名前でSLPサービスに登録されることの確認が表示されます。

    6. IIOP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-f \ 
        -Durl="service:jmx:iiop:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        slp.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-fです
      • サービスURLは、RMI over IIOPとして選択されるコネクタを指定し、RMIコネクタ・スタブが保存される外部ディレクトリは、セクション「初期設定」jndildapと特定したLDAPサーバーです。
      • スタブはLDAPサーバーのTestドメイン・コンポーネントに登録されます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-fでSLPサービスに登録されることの確認が表示されます。

    • Clientを起動します。
    • 選択したトランスポートおよび外部ディレクトリを使用してServerを起動したあと、Clientを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
           -Djava.naming.security.principal="$principal" \ 
           -Djava.naming.security.credentials="$credentials" \ 
           slp.Client 
       
      

      Serverで作成され検索サービスに登録されたエージェントの検出を確認する出力が表示されます。また、エージェントに設定された接続の接続名と、接続の確認が表示されます。

      特定のエージェントを検索するには、次のコマンドを入力します。

       
      $ java -classpath .:$classp -Ddebug=true \  
           -Djava.naming.security.principal="$principal" \ 
           -Djava.naming.security.credentials="$credentials" \ 
           -Dagent.name="agentName" \ 
          slp.Client 
       
      

      上記のコマンドで、agentNameは検索するエージェントの名前です。また、*を使用してエージェント名を部分的に指定することもできます。たとえば、文字xで始まるすべてのエージェント名を検索する場合は、x*と指定します。

Jini検索サービス

この例の目的は、JMXテクノロジのコネクタ・クライアントで、Jini検索サービスに登録されたコネクタ・サーバーを検索し、接続する方法を示すことです。この例では、次の操作を実行します。

  • エージェント側:
  • MBeanサーバーを作成
  • コネクタ・サーバーを作成
  • Jini検索サービスにコネクタ・アドレスを登録
  • クライアント側:
  • Jini検索サービスのポインタを取得
  • Jini検索サービスに登録されたすべてのコネクタ・サーバーを検索
  • JMX Remote APIコネクタを作成
  • MBeanサーバーのMBeanに関する情報を取得

Jini検索サービスの例は、ディレクトリwork_dir/jmx_examples/Lookup/jini内にあります。


注 -これらの例題では、ユーザーがJiniネットワーク・テクノロジに習熟していることを前提としています。Jiniネットワーク・テクノロジに関するドキュメントは、http://java.net/projects/jiniで入手できます。Jiniネットワーク・テクノロジは、http://java.net/projects/jiniからダウンロードできます。この例では、Jini Technology Starter Kit Version 1.2.1_002を使用して実装しています。
  1. work_dir/jmx_examples/Lookup/jiniディレクトリを開きます。

    このディレクトリ内には、次のファイルがあります。

    • Server.java
    • Client.java
    • java.policy
    • jini.properties.template
    • README
  2. テキスト・エディタでそれぞれのファイルを開きます。

    これらのクラスについて、以降のセクションで分析します。

例題クラスの分析

次のセクションでは、Jini検索サービスの例題で使用される各クラスを分析し、各クラスが上記で説明した操作をどのように実行するかについて説明します。

Server.java

Jini検索サービスのServer.javaクラスは、その大きさにより、一連のコード例として示されています。

コード例4-1 Jini検索サービスの例クラスServer.java (抜粋1)
 
 
public class Server { 
   private final MBeanServer mbs; 
   private static boolean debug = false; 
   public Server() { 
     mbs = MBeanServerFactory.createMBeanServer(); 
   } 
 
[...] 
 

コード例4-1に、MBeanサーバーmbsの作成を示します。SLPの例題の場合と同様に、Serverをコマンド行で起動する場合、JMXサービスのURLとエージェント名がサーバーに渡されます。

コード例4-2 Jini検索サービスの例クラスServer.java (抜粋2)
 
 
[...] 
 
   public JMXConnectorServer rmi(String url) 
      throws IOException, JMException, ClassNotFoundException { 
      JMXServiceURL jurl = new JMXServiceURL(url); 
      final HashMap env = new HashMap(); 
      // Environment map attributes 
     [...] 
     JMXConnectorServer rmis = 
        JMXConnectorServerFactory.newJMXConnectorServer(jurl, env, mbs); 
 
     final String agentName = System.getProperty("agent.name", 
                                                 "DefaultAgent"); 
 
     start(rmis,env,agentName); 
 
     return rmis; 
   } 
    
[...] 
 

コード例4-2に、環境マップenvとアドレスjurlで定義されるシステム・プロパティを使用した、RMIコネクタ・サーバーrmisの作成を示します。

RMIコネクタ・サーバーrmisが起動します。RMIコネクタ・サーバーのアドレスは、agentNameの名前でJini検索サービスに登録されます。

コード例4-3 Jini検索サービスの例クラスServer.java (抜粋3)
 
[...] 
 
   public void start(JMXConnectorServer server, Map env, String agentName) 
      throws IOException, ClassNotFoundException { 
      server.start(); 
      final ServiceRegistrar registrar=getRegistrar(); 
      final JMXConnector proxy = server.toJMXConnector(env); 
      register(registrar,proxy,agentName); 
   } 
    
   public static ServiceRegistrar getRegistrar() 
      throws IOException, ClassNotFoundException, 
         MalformedURLException { 
      final String jurl = 
         System.getProperty("jini.lookup.url","jini://localhost"); 
      final LookupLocator lookup = new LookupLocator(jurl); 
      final ServiceRegistrar registrar = lookup.getRegistrar(); 
      if (registrar instanceof Administrable) 
          debug("Registry is administrable."); 
      return registrar; 
   } 
    
   public static ServiceRegistration register(ServiceRegistrar registrar, 
                                              JMXConnector proxy, String name) 
      throws IOException { 
      Entry[] serviceAttrs = new Entry[] { 
              new net.jini.lookup.entry.Name(name) 
                       }; 
                        
      System.out.println("Registering proxy: AgentName=" + name ); 
      debug("" + proxy); 
      ServiceItem srvcItem = new ServiceItem(null, proxy, serviceAttrs); 
      ServiceRegistration srvcRegistration = 
             registrar.register(srvcItem, Lease.ANY); 
      debug("Registered ServiceID: " + 
                              srvcRegistration.getServiceID().toString()); 
      return srvcRegistration; 
   } 
    
[...] 
 

コード例4-3に、環境マップenvとサービスURL jurlを使用した、コネクタ・サーバーserverの作成を示します。コネクタ・サーバーのインスタンス・サーバーは、Jini検索サービス・メソッドLookupLocator.getRegistrar()を呼び出してJini検索サービスのポインタを取得します。

コネクタ・サーバーは、Jini検索サービス・ロケータregistrarと、コネクタ・サーバーが登録される際のエージェント名を使用して、プロキシ形式でJini検索サービスに登録されます。プロキシは実際には、コネクタ・サーバーのクライアント・スタブになり、JMXConnectorServertoJMXConnector()メソッドの呼出しにより取得されます。

登録自体は、サービス項目の配列を使用し、Jini検索サービス・クラスServiceRegistrarregister()メソッドを呼び出して実行されます。

Client.java

Jini検索サービスの例題クラスClient.javaコード例4-1に示します。

コード例4-1 Jini検索サービス例題クラスClient.java
 
 
public class Client { 
 
   private static boolean debug = false; 
   public static ServiceRegistrar getRegistrar() 
       throws IOException, ClassNotFoundException, MalformedURLException { 
       final String jurl = 
                  System.getProperty("jini.lookup.url","jini://localhost"); 
       final LookupLocator lookup = new LookupLocator(jurl); 
       final ServiceRegistrar registrar = lookup.getRegistrar(); 
       if (registrar instanceof Administrable) 
               debug("Registry is administrable."); 
       return registrar; 
 } 
 
   public static List lookup(ServiceRegistrar registrar, 
           String name) throws IOException { 
       final ArrayList list = new ArrayList(); 
       final Class[] classes = new Class[] {JMXConnector.class}; 
       final Entry[] serviceAttrs = new Entry[] { 
           new net.jini.lookup.entry.Name(name) 
   }; 
    
   ServiceTemplate template = 
        new ServiceTemplate(null,classes,serviceAttrs); 
   ServiceMatches matches = 
        registrar.lookup(template, Integer.MAX_VALUE); 
   for(int i = 0; i < matches.totalMatches; i++) { 
        debug("Found Service: " + matches.items[i].serviceID); 
        if (debug) { 
           if (matches.items[i].attributeSets != null) { 
                   final Entry[] attrs = matches.items[i].attributeSets; 
                   for (int j = 0; j < attrs.length ; j++) { 
                       debug("Attribute["+j+"]=" + attrs[j]); 
               } 
           } 
        } 
 
 
        if(matches.items[i].service != null) { 
            JMXConnector c = (JMXConnector)(matches.items[i].service); 
            debug("Found a JMXConnector: " + c); 
            list.add(c); 
        } 
   } 
   return list; 
} 
 
[...] 
 

コード例4-1に、コネクタ・クライアントがlookup.getRegistrar()の呼出しによりJini検索サービスのポインタを取得する方法を示します。クライアントは、次にエージェント名nameを使ってJini検索サービスにエントリとして登録されたコネクタのリストを取得します。SLPの例と異なり、起動時にユーザーがClientに渡したエージェント名は、既存のエージェント名と完全に一致するか、Nullでなければならず、いずれの場合も、Jini検索サービスはすべてのエージェントを検索します。

ここにコードは示されていませんが、コネクタのリストが取得されると、クライアントはServerによって起動したMBeanサーバーに接続し、このサーバーに登録されたすべてのMBeanを示したリストを取得します。

java.policy

java.policyファイルは、この例のために構成されたJavaテクノロジのセキュリティ・ポリシー・ファイルです。

jini.properties.template

この例のために構成された、テンプレート形式のJiniネットワーキング・テクノロジ・プロパティ・ファイル。@INSTALL_HOME_FOR_JINI@を変更し、ファイル名をjini.propertiesに変更します。

Jini検索サービスの例題の実行

Jini検索サービスを使用する検索サービスの例題を実行するには、セクション「初期設定」で実行した作業のほかにも、この例題に固有の初期作業を事前に実行する必要があります。Jiniネットワーク・テクノロジを、JMXテクノロジでサポートされるコネクタとともに使用してコネクタの検索を開始できます。

例題を実行する場合、作成されたエージェントの種類と、エージェントの作成に使用されたトランスポートを追跡するために、対応するセクションの文字列に等しい文字サフィックスがエージェント名に含まれています。たとえば、セクションa「外部ディレクトリを使用しないJRMP上のRMIコネクタ」のエージェントはexample-server-aと呼ばれます。

Jini検索サービスの例題の設定

次の手順は、この例題で実行できるすべてのトランスポートで要求されます。

  1. 例題クラスのコンパイルおよび実行が容易になるように、追加の環境変数をいくつか定義します。

    セクション「初期設定」で設定した共通の環境変数のほかに、Jini検索サービスのパスを追加できます。Jiniネットワーキング・テクノロジをインストールしたディレクトリは、jini_dirとして参照されます。

    $ JINI_HOME=jini_dir

    $ JINILIB=$JINI_HOME/lib

  2. classp環境変数を定義します。

    この例では、Jini検索サービスのコアと拡張機能に使用するJARファイルが必要になります。

    $ classp=$JINILIB/jini-core.jar:$JINILIB/jini-ext.jar

  3. jini.propertiesファイルを作成します。

    Solaris、Linux、またはMac OS Xプラットフォーム用のプロパティ・ファイルは、この例のクラスと同じディレクトリ内にあります。Solaris、Linux、またはMac OS Xプラットフォームを実行していない場合、使用しているプラットフォームのプロパティ・ファイルは次のディレクトリで入手できます。

    $JINI_HOME/example/launcher/jini12_<platform>.properties

  4. jini.propertiesファイルを更新します。

    更新により、システムに必要なすべてのパス、ホスト名、ポート番号がファイルに指定されなければなりません。Solaris、Linux、またはMac OS Xプラットフォームを実行していない場合でも、参照として添付のテンプレートを使用できます。

  5. Jiniネットワーキング・テクノロジStartServiceを起動します。

    $ java -cp $JINILIB/jini-examples.jar com.sun.jini.example.launcher.StartService &

    StartServiceグラフィカル・ユーザー・インタフェースが開きます。

  6. 各自のjini.propertiesファイルをStartServiceにロードします。

    「File」と「Open Property File」を順にクリックし、work_dir/jmx_examples/Lookup/jiniからプロパティ・ファイルを選択します。

  7. Jini検索サービスを開始します。

    必要なJini検索サービスを開始するには、「Run」タブをクリックし、次の項目のそれぞれについて「START」ボタンを押します。

    • RMID
    • WebServer
    • Reggie
    • LookupBrowser

    サービスの実行を確認するメッセージが表示されます。

  8. ClientおよびServerクラスをコンパイルします。

    次のコマンドを入力します。

    $ javac -d .-classpath $classp Server.java Client.java

Jini検索サービスの例題の実行

この例では、Jini検索サービスを使用して、RMIのデフォルトのトランスポートであるJRMP、およびIIOPトランスポートを使用するRMIコネクタ・サーバーを検索する方法を示します。そのほか、セクション「初期設定」で説明したように、RMIコネクタ・スタブの登録には別の外部ディレクトリが使用されています。

ここに示すトランスポートと外部ディレクトリの組み合わせは次のとおりです。

  • 次のものを使用した、JRMPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • RMIレジストリ
  • LDAPレジストリ
  • 次のものを使用した、IIOPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • CORBAネーム・サービス
  • LDAPレジストリ
  1. Serverを起動します。

    Serverの起動に使用するコマンドは、使用している外部ディレクトリによって異なります。Clientを起動する前に、各種のトランスポートおよび外部レジストリを使用して、Serverの次のインスタンスの1つまたは複数を起動できます。

    1. 外部ディレクトリを使用しないJRMP上のRMIコネクタ。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-a \ 
        -Durl="service:jmx:rmi://" \ 
        -Djava.security.policy=java.policy \ 
        jini.Server & 
       
      

      このコマンドで、

      • debugtrueに設定され、Serverの実行時の画面出力をより詳細なものにします。
      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています。
      • 作成されるエージェントの名前はexample-server-aです。
      • サービスURLにより、RMIのデフォルト・トランスポートJRMP上で動作するRMIコネクタの選択が指定されます。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがJini検索サービスに登録されることの確認が表示されます。

    2. JRMP上のRMIコネクタ。外部ディレクトリにRMIレジストリを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-b \ 
        -Durl="service:jmx:rmi:///jndi/${jndirmi}/server" \ 
        -Djava.security.policy=java.policy \ 
        jini.Server & 
       
      

      このコマンドで、

      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています。
      • 作成されるエージェントの名前はexample-server-bです。
      • サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」jndirmiと特定したRMIレジストリです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがJini検索サービスに登録されることの確認が表示されます。

    3. JRMP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-c \ 
        -Durl="service:jmx:rmi:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.security.policy=java.policy \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jini.Server & 
       
      

      このコマンドで、

      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています。
      • 作成されるエージェントの名前はexample-server-cです。サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブが保存される外部ディレクトリは、セクション「初期設定」jndildapと特定したLDAPサーバーです。
      • スタブはLDAPサーバーのTestドメイン・コンポーネントに登録されます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-cでJini検索サービスに登録されることの確認が表示されます。

    4. 外部ディレクトリを使用しないIIOP上のRMIコネクタ。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-d \ 
        -Durl="service:jmx:iiop://" \ 
        -Djava.security.policy=java.policy \ 
        jini.Server & 
       
      

      このコマンドで、

      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています
      • 作成されるエージェントの名前はexample-server-dです
      • サービスURLは、IIOP上のRMIコネクタとして選択されるコネクタを指定します。

      Serverが起動すると、RMIコネクタの作成、および自動的に生成されたURLのJini検索サービスへの登録を確認するメッセージが表示されます。

    5. IIOP上のRMIコネクタ。外部ディレクトリにCORBAを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-e \ 
        -Durl="service:jmx:iiop:///jndi/${jndiiiop}/server" \ 
        -Djava.security.policy=java.policy \ 
        jini.Server & 
       
      

      このコマンドで、

      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています。
      • 作成されるエージェントの名前はexample-server-eです。
      • サービスURLは、IIOP上のRMIコネクタとして選択されるコネクタを指定します。RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」jndiiiopと特定したCORBAネーム・サービスです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがexample-server-eという名前でJini検索サービスに登録されることの確認が表示されます。

    6. IIOP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=example-server-f \ 
        -Durl="service:jmx:iiop:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.security.policy=java.policy \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jini.Server & 
       
      

      このコマンドで、

      • Jini検索サービスへのアクセスを可能にする、セキュリティ・ポリシーが指定されています。
      • 作成されるエージェントの名前はexample-server-fです。
      • サービスURLは、RMI over IIOPとして選択されるコネクタを指定します。
      • スタブはLDAPサーバーのTestドメイン・コンポーネントに登録されます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-fでJini検索サービスに登録されることの確認が表示されます。

    • Clientを起動します。
    • 選択したトランスポートおよび外部ディレクトリを使用してServerを起動したあと、Clientを起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Djava.security.policy=java.policy \ 
        jini.Client 
       
      

      Serverで作成され検索サービスに登録されたエージェントの検出を確認する出力が表示されます。また、エージェントに設定された接続の接続名と、接続の確認が表示されます。

      次のコマンドを入力すると、特定のエージェントを検索できます。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Djava.security.policy=java.policy \ 
        -Dagent.name=agentName \ 
        jini.Client 
       
      

      上記のコマンドで、agentNameは検索するエージェントの名前です。また、*を使用してエージェント名を部分的に指定することもできます。たとえば、文字xで始まるすべてのエージェント名を検索する場合は、x*と指定します。

Java Naming and Directory Interface (JNDI)/LDAP検索サービス

JMXテクノロジでは、LDAPレジストリをバックエンドとして使用して、JNDI検索サービスにRMIコネクタを登録できます。この例では、次の操作を実行します。

  • エージェント側:
  • MBeanサーバーを作成
  • コネクタ・サーバーを作成
  • LDAPサーバーにコネクタ・アドレスを登録
  • クライアント側:
  • JNDI/LDAP検索サービスのポインタを取得
  • JNDI/LDAP検索サービスに登録されたすべてのコネクタ・サーバーを検索
  • JMX Remote APIコネクタを作成
  • MBeanサーバーのMBeanに関する情報を取得

JNDI/LDAP検索の例は、ディレクトリwork_dir/jmx_examples/Lookup/ldap内にあります。

  1. work_dir/jmx_examples/Lookup/ldapディレクトリを開きます。

    このディレクトリ内には、次のファイルがあります。

    • Server.java
    • Client.java
    • jmx-schema.txt
    • 60jmx-schema.ldif
    • README
  2. テキスト・エディタでファイルを開きます。

    これらのクラスについて、以降のセクションで分析します。

例題クラスの分析

次のセクションでは、JNDI/LDAP検索サービスの例題で使用される各クラスを分析し、各クラスが上記で説明した操作をどのように実行するかについて説明します。

Server.java

JNDI/LDAP検索サービスのServer.javaクラスは、その大きさにより、一連のコード例として示されています。

コード例4-1 JNDI/LDAP検索サービスの例Server.java (抜粋1)
 
[...] 
 
public class Server { 
   public final static int JMX_DEFAULT_LEASE = 60; 
   private static boolean debug = false; 
   private final MBeanServer mbs; 
   public Server() { 
      mbs = MBeanServerFactory.createMBeanServer(); 
   } 
 
  public static DirContext getRootContext() throws NamingException { 
      final Hashtable env = new Hashtable(); 
 
      final String factory = 
        System.getProperty(Context.INITIAL_CONTEXT_FACTORY, 
                           "com.sun.jndi.ldap.LdapCtxFactory"); 
      final String ldapServerUrl = 
        System.getProperty(Context.PROVIDER_URL); 
      final String ldapUser = 
        System.getProperty(Context.SECURITY_PRINCIPAL, 
                           "cn=Directory Manager"); 
      final String ldapPasswd = 
        System.getProperty(Context.SECURITY_CREDENTIALS); 
      debug(Context.PROVIDER_URL + "=" + ldapServerUrl); 
      debug(Context.SECURITY_PRINCIPAL + "=" + ldapUser); 
      if (debug) { 
                  System.out.print(Context.SECURITY_CREDENTIALS + "="); 
                  final int len = (ldapPasswd==null)?0:ldapPasswd.length(); 
                  for (int i=0;i<len;i++) System.out.print("*"); 
                  System.out.println(); 
      } 
      env.put(Context.INITIAL_CONTEXT_FACTORY,factory); 
      env.put(Context.SECURITY_PRINCIPAL, ldapUser); 
      if (ldapServerUrl != null) 
           env.put(Context.PROVIDER_URL, ldapServerUrl); 
      if (ldapPasswd != null) 
           env.put(Context.SECURITY_CREDENTIALS, ldapPasswd); 
      InitialContext root = new InitialLdapContext(env,null); 
      return (DirContext)(root.lookup("")); 
  } 
   
[...] 
 

コード例4-1に、MBeanサーバーmbsの初期作成、およびコネクタ・サーバーのアドレスが登録されるLDAPディレクトリ・ツリーのルート・コンテキストのポインタの取得を示します。プロバイダURL、LDAPユーザー名、セキュリティ資格などの関連するLDAPアクセス変数はすべてここに指定され、環境マップenvに渡されます。環境マップenvは、このあと、InitialLdapContextの呼出しにパラメータとして渡され、これによって初期LDAPコンテキストが取得されます。

コード例4-1では省略されていますが、コネクタがLDAPサーバーに登録される際のエージェント名が取得されます。

コード例4-2 JNDI/LDAP検索サービスの例Server.java (抜粋2)
[...] 
 
public static void register(DirContext root, 
                           JMXServiceURL jmxUrl, 
                           String name) 
   throws NamingException, IOException { 
 
   final String mydn = System.getProperty("dn","cn="+name); 
 
   debug("dn: " + mydn ); 
 
   Object o = null; 
   try { 
       o = root.lookup(mydn); 
   } catch (NameNotFoundException n) { 
       Attributes attrs = new BasicAttributes(); 
       Attribute objclass = new BasicAttribute("objectClass"); 
       objclass.add("top"); 
       objclass.add("javaContainer"); 
       objclass.add("jmxConnector"); 
       attrs.put(objclass); 
       attrs.put("jmxAgentName", name); 
       o = root.createSubcontext(mydn,attrs); 
   } 
   if (o == null) throw new NameNotFoundException(); 
   final Attributes attrs = root.getAttributes(mydn); 
   final Attribute oc = attrs.get("objectClass"); 
   if (!oc.contains("jmxConnector")) { 
       final String msg = "The supplied node [" + mydn +  
         "] does not contain the jmxConnector objectclass"; 
       throw new NamingException(msg); 
   } 
    
   final Attributes newattrs = new BasicAttributes(); 
   newattrs.put("jmxAgentName",name); 
   newattrs.put("jmxServiceURL",jmxUrl.toString()); 
   newattrs.put("jmxAgentHost",InetAddress.getLocalHost().getHostName()); 
   newattrs.put("jmxProtocolType",jmxUrl.getProtocol()); 
   newattrs.put("jmxExpirationDate", 
                getExpirationDate(JMX_DEFAULT_LEASE)); 
   root.modifyAttributes(mydn,DirContext.REPLACE_ATTRIBUTE,newattrs); 
} 
 
[...] 
 

コード例4-2に、JMXコネクタ・サーバーのサービスURLのLDAPディレクトリへの登録を示します。URLが登録されるDNは、コマンド行のdnシステム・プロパティ、すなわち-Ddn=mydnを使用して渡すことができます(後述のサーバーの起動に使用されるコマンドを参照)。dnシステム・プロパティが指定されない場合、DN: cn=nameを使用できます。ここで、nameagentNameです。もっとも、必ずしもこれを使用する必要はありません。実際にはURLが登録される場所は問題になりません。クライアント・コードで直接そのDNが使用されることはないためです。その代わり、LDAP検索を実行して、補助的なjmxConnector ObjectClassを含むノードが検索されます。ここで重要になるのは、各URLが個々のLDAPノードに登録されるという点です。これらのノードの命名方式は、LDAP管理者、この場合は各ユーザーに委ねられます。この例では、ノードcn=nameの作成が可能なrootコンテキストを作成する方法でLDAPサーバーを構成し、このrootコンテキストを、Context.PROVIDER_URLプロパティを通じてLDAPの初期コンテキストに渡しているものと仮定しています(コード例4-1を参照)。

コード例4-2のコードでは、サーバーURLを登録するノードが存在するかどうかをチェックしています。存在しない場合、ノードの作成を試みてください(親ノードが存在していない場合は失敗する)。jmxConnector ObjectClassは簡単な補助クラスであるため、新しいコンテキストを作成する必要がある場合は、構造化クラスとしてjavaContainer ObjectClassを使用します。この場合も、必ずしもこのクラスを使用する必要はありません。jmxConnector補助クラスを追加できる構造化クラスであれば、何でもかまいません。コードは次にサーバーを登録するノードに、jmxConnector補助クラスがすでに使用されているかどうかをチェックします。使用されていない場合は、例外がスローされます。

この時点で、URLを登録するノードが存在し、適切なjmxConnector補助クラスが指定されていることが確実になります。このため、あとはLDAP検索のためのJMX Remote APIで定義された属性の値を置き換えるだけです(jmx-schema.txtを参照)。

  • jmxServiceUrl: サーバーの起動後にserver.getAddress()により取得されたString形式のサーバーURLが含まれる
  • jmxAgentName: JMXエージェント名が含まれる
  • jmxProtocolType: jmxUrl.getProtocolType()で返されるJMXプロトコル型が含まれる
  • jmxAgentHost: エージェント・ホストの名前が含まれる
  • jmxExpirationDate: URLの有効期日が含まれる。
コード例4-3 JNDI/LDAP検索サービスの例Server.java (抜粋3)
 
[...] 
 
   public JMXConnectorServer rmi(String url) 
     throws IOException, JMException, 
        NamingException, ClassNotFoundException { 
 
     JMXServiceURL jurl = new JMXServiceURL(url); 
     final HashMap env = new HashMap(); 
     // Prepare the environment Map 
     
[...] 
 
     JMXConnectorServer rmis = 
        JMXConnectorServerFactory.newJMXConnectorServer(jurl, env, mbs); 
 
     final String agentName = System.getProperty("agent.name", 
                                                 "DefaultAgent"); 
     start(rmis,env,agentName); 
     return rmis; 
   } 
     
[...] 
 

コード例4-3では、JMXサービスURL jurlと適切なLDAPプロパティが環境マップenvに渡され、rmisという新しいRMIコネクタ・サーバーが作成されています。コネクタ・サーバーrmisが、JMXConnectorServer.start()の呼出しにより起動し、LDAPサーバーに登録されます。

コード例4-4 JNDI/LDAP検索サービスの例Server.java (抜粋4)
 
[...] 
 
    public void start(JMXConnectorServer server, Map env, String agentName) 
       throws IOException, NamingException { 
       server.start(); 
       final DirContext root=getRootContext(); 
       final JMXServiceURL address = server.getAddress(); 
       register(root,address,agentName); 
    } 
     
[...] 
 

コード例4-4に、JMXコネクタ・サーバーserverの作成、LDAPサーバーのルート・ディレクトリrootのポインタの取得、およびaddressという名前のserverのURLの作成を示します。ルート・ディレクトリ、URL、およびエージェント名は、パラメータとしてregister()に渡され、LDAPサーバーに登録されます。

Client.java

JNDI/LDAP検索サービスのClient.javaクラスをコード例4-1に示します。

コード例4-1 JNDI/LDAP検索サービスの例Client.java
 
[...] 
 
public class Client { 
 
   private static boolean debug = false; 
 
   public static void listAttributes(DirContext root, String dn) 
     throws NamingException { 
     final Attributes attrs = root.getAttributes(dn); 
     System.out.println("dn: " + dn); 
     System.out.println("attributes: " + attrs); 
   } 
    
   public static DirContext getRootContext() throws NamingException { 
      final Hashtable env = new Hashtable(); 
      // Prepare environment map 
      [...] 
       
      InitialContext root = new InitialLdapContext(env,null); 
      return (DirContext)(root.lookup("")); 
   } 
    
   // Confirm URL has not expired  
  [...]  
 
   public static List lookup(DirContext root, String protocolType, 
                             String name) 
      throws IOException, NamingException { 
      final ArrayList list = new ArrayList(); 
      String queryProtocol = 
         (protocolType==null)?"":"(jmxProtocolType="+protocolType+")"; 
      String query = 
          "(&" + "(objectClass=jmxConnector) " + 
          "(jmxServiceURL=*) " + 
          queryProtocol + 
          "(jmxAgentName=" + ((name!=null)?name:"*") + "))"; 
 
      SearchControls ctrls = new SearchControls(); 
      ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE); 
      final NamingEnumeration results = root.search("", query, ctrls); 
      while (results.hasMore()) {  
           final SearchResult r = (SearchResult) results.nextElement(); 
           debug("Found node: " + r.getName()); 
           final Attributes attrs = r.getAttributes(); 
           final Attribute attr = attrs.get("jmxServiceURL"); 
           if (attr == null) continue; 
           final Attribute exp = attrs.get("jmxExpirationDate"); 
           if ((exp != null) && hasExpired((String)exp.get())) { 
               System.out.print(r.getName() + ": "); 
               System.out.println("URL expired since: " + exp.get()); 
               continue; 
           }   
           final String urlStr = (String)attr.get(); 
           if (urlStr.length() == 0) continue; 
 
    
           debug("Found URL: "+ urlStr); 
 
    
           final JMXServiceURL url = new JMXServiceURL(urlStr); 
           final JMXConnector conn = 
               JMXConnectorFactory.newJMXConnector(url,null); 
           list.add(conn); 
           if (debug) listAttributes(root,r.getName()); 
      } 
 
      return list; 
 
   }   
} 
 

コード例4-1では、ClientはまずLDAPディレクトリDirContextのポインタrootを返し、次にこのディレクトリでjmxConnector型のオブジェクト・クラスを検索します。jmxConnectorオブジェクト・クラスのサービスURLと有効期日属性、attrexpが取得され、expのチェックによりURLが有効期限内であることが確認され、JMXConnectorFactoryの呼出しにより新しいコネクタconnが作成されます。コネクタconnがコネクタのリストに追加され、MBeanサーバー内のServerで作成されたMBeanへのアクセスに使用されます。

jmx-schema.txt

jmx-schema.txtファイルは、JMX Remote API用のLDAPスキーマ・ファイルです。

60jmx-schema.ldif

60jmx-schema.ldifファイルは、JMXテクノロジのLDAPスキーマ・ファイルjmx-schema.txtに対応するldifファイルです。Sun ONE Directory Serverを使用している場合、このファイルをSun ONE Directory Serverのconfig/schemaディレクトリに直接コピーできます(セクション「JNDI/LDAP検索サービスの例題の設定」を参照)。

JNDI/LDAP検索サービスの例題の実行

JNDI/LDAP検索サービスを使用する検索サービスの例題を実行するには、セクション「初期設定」で実行した作業のほかにも、この例題に固有の初期作業を事前に実行する必要があります。JNDI/LDAPネットワーク・テクノロジを、JMXテクノロジでサポートされる2つのコネクタとともに使用してコネクタの検索を開始できます。

例題を実行する場合、作成されたエージェントの種類と、エージェントの作成に使用されたトランスポートを追跡するために、対応するセクションの文字列に等しい文字サフィックスがエージェント名に含まれています。たとえば、セクションa「外部ディレクトリを使用しないJRMP上のRMIコネクタ」のエージェントはexample-server-aと呼ばれます。

JNDI/LDAP検索サービスの例題の設定

次の手順は、この例題で実行できる各種のコネクタ/トランスポートのすべての組み合わせで要求されます。

  1. セクション「初期設定」で起動したLDAPサーバーを停止します。

    これは使用しているLDAPサーバーの種類に合わせて実行します。

  2. JMXテクノロジのスキーマを、使用しているLDAPサーバーのschemaディレクトリにコピーします。

    たとえば、Sun ONE Directory Server 5.0を使用している場合、次のように入力します。

    $ cp 60jmx-schema.ldif /var/ds5/slapd-<hostname>/config/schema

    そのほかのLDAPサーバーについては、使用しているLDAPサーバーの種類に合わせて実行します。

  3. LDAPサーバーを再起動します。

    これは使用しているLDAPサーバーの種類に合わせて実行します。

  4. ServerがそのサービスURLを登録するルートを定義します。

    Serverセクション「初期設定」で作成したドメイン・コンポーネントのサフィックスdc=Testのパスを指定する必要があります。

    $ provider="ldap://$ldaphost:$ldapport/dc=Test"

  5. ClientおよびServerクラスをコンパイルします。

    $ javac -d . Server.java Client.java

RMIコネクタを使用したJNDI/LDAP検索サービスの例題の実行

この例では、JNDI/LDAP検索サービスを使用して、RMIのデフォルトのトランスポートであるJRMP、およびIIOPトランスポートを使用するRMIコネクタ・サーバーを検索する方法を示します。そのほか、セクション「初期設定」で説明したように、RMIコネクタ・スタブの登録には別の外部ディレクトリが使用されています。

ここに示すトランスポートと外部ディレクトリの組み合わせは次のとおりです。

  • 次のものを使用した、JRMPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • RMIレジストリ
  • LDAPレジストリ
  • 次のものを使用した、IIOPトランスポート上のRMIコネクタ
  • 外部ディレクトリなし
  • CORBAネーム・サービス
  • LDAPレジストリ
  1. Serverを起動します。

    Serverの起動に使用するコマンドは、使用している外部ディレクトリによって異なります。Clientを起動する前に、各種のトランスポートおよび外部レジストリを使用して、Serverの次のインスタンスの1つまたは複数を起動できます。

    1. 外部ディレクトリを使用しないJRMP上のRMIコネクタ。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-a \ 
        -Durl="service:jmx:rmi://" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • debugはtrueに設定され、Serverの実行時の画面出力をより詳細なものにします。
      • 作成されるエージェントの名前はexample-server-aです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLにより、RMIのデフォルト・トランスポートJRMP上で動作するRMIコネクタの選択が指定されます。

      サーバーが起動すると、RMIコネクタの作成、およびそのURLのJNDI/LDAP検索サービスへの登録を確認するメッセージが表示されます。

    2. JRMP上のRMIコネクタ。外部ディレクトリにRMIレジストリを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-b \ 
        -Durl="service:jmx:rmi:///jndi/${jndirmi}/server" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-bです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」jndirmiと特定したRMIレジストリです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLのJNDI/LDAP検索サービスへの登録を確認するメッセージが表示されます。

    3. JRMP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-c \ 
        -Durl="service:jmx:rmi:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-cです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLは、RMI over JRMPとして選択されるコネクタを指定し、RMIコネクタ・スタブが保存される外部ディレクトリは、セクション「初期設定」jndildapと特定したLDAPサーバーです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-cでJNDI/LDAP検索サービスに登録されることの確認が表示されます。

    4. 外部ディレクトリを使用しないIIOP上のRMIコネクタ。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-d \ 
        -Durl="service:jmx:iiop://" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-dです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLは、選択されるコネクタがIIOP上で動作するRMIコネクタであることを指定します。

      Serverが起動すると、RMIコネクタの作成、および自動的に生成されたURLのJNDI/LDAP検索サービスへの登録を確認するメッセージが表示されます。

    5. IIOP上のRMIコネクタ。外部ディレクトリにCORBAを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-e \ 
        -Durl="service:jmx:iiop:///jndi/${jndiiiop}/server" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-eです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLは、IIOP上のRMIコネクタとして選択されるコネクタを指定します。RMIコネクタ・スタブserverが保存される外部ディレクトリは、セクション「初期設定」jndiiiopと特定したCORBAネーム・サービスです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがexample-server-eという名前でJNDI/LDAP検索サービスに登録されることの確認が表示されます。

    6. IIOP上のRMIコネクタ。外部ディレクトリにLDAPを使用します。

      次のコマンドを入力してServerを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Dagent.name=example-server-f \ 
        -Durl="service:jmx:iiop:///jndi/${jndildap}/cn=x,dc=Test" \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Server & 
       
      

      このコマンドで、

      • 作成されるエージェントの名前はexample-server-fです。
      • エージェントが登録されるドメイン・コンポーネントのサフィックスを示すURL、providerが与えられます。
      • LDAPサーバーにアクセスするため、共通名の属性principalとパスワードcredentialsが与えられます。
      • サービスURLは、RMI over IIOPとして選択されるコネクタを指定し、RMIコネクタ・スタブが保存される外部ディレクトリは、セクション「初期設定」jndildapと特定したLDAPサーバーです。

      Serverが起動すると、RMIコネクタの作成、およびそのURLがエージェント名example-server-fでJNDI/LDAP検索サービスに登録されることの確認が表示されます。

    • Clientを起動します。
    • 選択したトランスポートおよび外部ディレクトリを使用してServerを起動したあと、Clientを起動します。

       
      $ java -classpath . -Ddebug=true \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        jndi.Client 
       
      

      Serverで作成され検索サービスに登録されたエージェントの検出を確認する出力が表示されます。また、エージェントに設定された接続の接続名と、接続の確認が表示されます。

      特定のエージェントを検索するには、次のコマンドを入力します。

       
      $ java -classpath . -Ddebug=true \ 
        -Djava.naming.provider.url="$provider" \ 
        -Djava.naming.security.principal="$principal" \ 
        -Djava.naming.security.credentials="$credentials" \ 
        -Dagent.name=agentName \ 
        jndi.Client 
       
      

      上記のコマンドで、agentNameは検索するエージェントの名前です。また、*を使用してエージェント名を部分的に指定することもできます。たとえば、文字xで始まるすべてのエージェント名を検索する場合は、x*と指定します。


目次||


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