目次 | 前へ | 次へ 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.java と Client.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 を登録する場合に使用します。SCOPE と agentName は、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 は、コネクタサーバーのアドレスであり、コネクタサーバーの起動時に JMXConnectorServer の getAddress() メソッドを呼び出して取得します。

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

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

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

JMX テクノロジサービス URL、jmxUrl は、SLP で取得されたエージェントごとに生成されます。各エージェントの SLP サービス URL、surl はパラメータとして JMXServiceURL インスタンスに渡されます。URL jmxUrl は、JMXConnectorFactory の newJMXConnector() メソッドに渡され、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 検索サービスは Locator の getLocator() メソッドを呼び出して検索されます。

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 ネットワークテクノロジ (現在は Apache River プロジェクト) に習熟していることを前提としています。この例では、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 検索サービスに登録されます。プロキシは実際には、コネクタサーバーのクライアントスタブになり、JMXConnectorServer の toJMXConnector() メソッドの呼び出しにより取得されます。

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

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 ファイルを作成します。

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

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

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

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

  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 & 
       
      

      このコマンドで、

      • debug は true に設定され、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 を使用できます。ここで、name は agentName です。もっとも、必ずしもこれを使用する必要はありません。実際には 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 と有効期日属性、attr と exp が取得され、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, 2013, Oracle and/or its affiliates. All rights reserved.