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

第 4 章

検索サービス

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

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

4.1 初期設定

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

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

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

4.1.1 外部 RMI レジストリ

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

  1. ローカルホストのポート 9999 で RMI レジストリを起動します。
  2. 「第 3 章 JMX コネクタ」の例と同様に、RMI レジストリは JRMP トランスポートを実装する RMI コネクタ用の RMI コネクタスタブを格納するために使用されます。

    $ rmiregistry 9999 &

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

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

4.1.2 外部 CORBA ネームサービス

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

  1. ローカルホストのポート 7777 で、Object Request Broker (ORB) デーモンを起動します。
  2. IIOP トランスポートを実装する RMI コネクタは、CORBA ネームを使用して RMI コネクタスタブを識別できます。

    $ orbd -ORBInitialPort 7777 &

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

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

4.1.3 外部 LDAP レジストリ

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

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

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

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

    dc=Test

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

  5. 便宜上、環境変数に次の LDAP パラメータを設定します。
  6. これらの変数は、外部 LDAP サーバに RMI コネクタスタブを登録する検索サービスの例で、Server クラスと Client クラスを起動するときに、入力するコマンドを短縮するために使用します。

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

    3. LDAP サーバが稼動するポート (ldap_port)
    4. $ ldapport=ldap_port

    5. LDAP コマンド名属性。次の例では、“Directory Manager”
    6. $ principal=”cn=Directory Manager”

    7. LDAP サーバで要求されるパスワード
    8. LDAP サーバのパスワードを指定します。

      $ credentials=your_ldap_password

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

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

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

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

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

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

  1. エージェント側:
    1. MBean サーバを作成
    2. SLP 検索サービスのポインタを取得
    3. コネクタサーバを作成
    4. SLP 検索サービスにコネクタアドレスを登録
  2. クライアント側:
    1. SLP 検索サービスのポインタを取得
    2. SLP 検索サービスに登録されたすべてのコネクタサーバを検索
    3. JMX Remote API コネクタを作成
    4. 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 を取得する必要があります。

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

  1. work_dir/jmx_examples/Lookup/slp を開きます。
  2. このディレクトリ内には、次のファイルがあります。

    • Server.java
    • Client.java
    • README
  3. テキストエディタで 2 つの *.java ファイルを開きます。
  4. これらのクラスについて、以降のセクションで分析します。

4.2.1 例題クラスの分析

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


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

4.2.1.1 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 検索サービスへの登録を示します。

4.2.1.2 Client.java

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

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

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

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

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

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

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

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

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

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

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

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

  1. クラスのコンパイルおよび実行が容易になるように、追加で環境変数を定義します。
  2. 「4.1 初期設定」で設定された共通の環境変数の他に、SLP サービスのパスを追加する必要があります。Solaris オペレーティング環境を使用している場合は、次の変数を追加します。

    $ SLPLIB=/usr/share/lib/slp

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

  3. classp 環境変数を定義し、エクスポートします。
  4. この例では、SLP の Java アーカイブ (JAR) ファイルを含むクラスパスが必要です。

    $ classp=$SLPLIB/slp.jar

  5. Client クラスと Server クラスの例題をコンパイルします。
  6. 次のコマンドを入力します。

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

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

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

    Password:[type superuser password]

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

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

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

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

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

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

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

    1. 外部ディレクトリを使用しない JRMP 上の RMI コネクタ
    2. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    3. JRMP 上の RMI コネクタ。外部ディレクトリに RMI レジストリを使用します。
    4. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    5. JRMP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    6. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    7. 外部ディレクトリを使用しない IIOP 上の RMI コネクタ
    8. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    9. IIOP 上の RMI コネクタ。外部ディレクトリに CORBA を使用します。
    10. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    11. IIOP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    12. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

  3. Client を起動します。
  4. 選択したトランスポートおよび外部ディレクトリを使用して 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* と指定します。

4.3 Jini 検索サービス

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

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

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


注 – これらの例題では、ユーザが Jini ネットワークテクノロジに習熟していることを前提としています。Jini ネットワークテクノロジのドキュメントは、http://wwws.sun.com/software/jini/specs/index.html で入手できます。Jini ネットワークテクノロジは、Sun Microsystems Community Source Licensing ページ、http://wwws.sun.com/software/communitysource/jini/download.html からダウンロードできます。この例では、Jini Technology Starter Kit Version 1.2.1_001 を使用して実装しています。
  1. work_dir/jmx_examples/Lookup/jini ディレクトリを開きます。
  2. このディレクトリ内に、次のファイルが見つかります。

    • Server.java
    • Client.java
    • java.policy
    • jini.properties.template
    • README
  3. テキストエディタでそれぞれのファイルを開きます。
  4. これらのクラスについて、以降のセクションで分析します。

4.3.1 例題クラスの分析

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

4.3.1.1 Server.java

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

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

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

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

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

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

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

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

4.3.1.2 Client.java

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

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

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

4.3.1.3 java.policy

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

4.3.1.4 jini.properties.template

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

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

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

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

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

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

  1. 例題クラスのコンパイルおよび実行が容易になるように、追加の環境変数をいくつか定義します。
  2. 「4.1 初期設定」で設定した共通の環境変数の他に、Jini サービスのパスを追加できます。Jini ネットワーキングテクノロジをインストールしたディレクトリは、jini_dir として参照されます。

    $ JINI_HOME=jini_dir

    $ JINILIB=$JINI_HOME/lib

  3. classp 環境変数を定義します。
  4. この例では、Jini 検索サービスのコアと拡張機能に使用する JAR ファイルが必要になります。

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

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

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

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

  9. Jini ネットワーキングテクノロジ StartService を起動します。
  10. $ java -cp $JINILIB/jini-examples.jar com.sun.jini.example.launcher.StartService &

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

  11. 各自の jini.properties ファイルを StartService にロードします。
  12. [File]、[Open Property File] をクリックし、work_dir/jmx_examples/Lookup/jini 内からプロパティファイルを選択します。

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

    • RMID
    • WebServer
    • Reggie
    • LookupBrowser

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

  15. Client クラスと Server クラスをコンパイルします。
  16. 次のコマンドを入力します。

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

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

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

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

  • 次のものを使用した、JRMP トランスポート上の RMI コネクタ
    • 外部ディレクトリなし
    • RMI レジストリ
    • LDAP レジストリ
  • 次のものを使用した、IIOP トランスポート上の RMI コネクタ
    • 外部ディレクトリなし
    • CORBA ネームサービス
    • LDAP レジストリ
  1. Server を起動します。
  2. Server の起動に使用するコマンドは、使用している外部ディレクトリによって異なります。Client を起動する前に、各種のトランスポートおよび外部レジストリを使用して、Server の次のインスタンスの 1 つまたは複数を起動できます。

    1. 外部ディレクトリを使用しない JRMP 上の RMI コネクタ
    2. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    3. JRMP 上の RMI コネクタ。外部ディレクトリに RMI レジストリを使用します。
    4. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    5. JRMP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    6. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=test-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 検索サービスへのアクセスを可能にする、セキュリティポリシーが指定されています。
      • 作成されるエージェントの名前は test-server-c です。サービス URL は、RMI over JRMP として選択されるコネクタを指定し、RMI コネクタスタブが保存される外部ディレクトリが、「4.1 初期設定」jndildap として特定した LDAP サーバであることを指定します。
      • スタブは LDAP サーバの Test ドメインコンポーネントに登録されます。
      • LDAP サーバにアクセスするため、共通名の属性 principal とパスワード credentials が指定されます。

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

    7. 外部ディレクトリを使用しない IIOP 上の RMI コネクタ
    8. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    9. IIOP 上の RMI コネクタ。外部ディレクトリに CORBA を使用します。
    10. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    11. IIOP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    12. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .:$classp -Ddebug=true \ 
        -Dagent.name=test-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 検索サービスへのアクセスを可能にする、セキュリティポリシーが指定されています。
      • 作成されるエージェントの名前は test-server-f です。
      • サービス URL は、RMI over IIOP として選択されるコネクタを指定します。
      • RMI コネクタスタブが保存される外部ディレクトリは、「4.1 初期設定」jndildap と特定した LDAP サーバです。
      • スタブは LDAP サーバの Test ドメインコンポーネントに登録されます。
      • LDAP サーバにアクセスするため、共通名の属性 principal とパスワード credentials が指定されます。

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

  3. Client を起動します。
  4. 選択したトランスポートおよび外部ディレクトリを使用して 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* と指定します。

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

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

  1. エージェント側:
    1. MBean サーバを作成
    2. コネクタサーバを作成
    3. LDAP サーバにコネクタアドレスを登録
  2. クライアント側:
    1. JNDI/LDAP 検索サービスのポインタを取得
    2. JNDI/LDAP 検索サービスに登録されたすべてのコネクタサーバを検索
    3. JMX Remote API コネクタを作成
    4. MBean サーバの MBean に関する情報を取得
  1. JNDI/LDAP 検索の例は、ディレクトリ work_dir/jmx_examples/Lookup/ldap 内にあります。work_dir/jmx_examples/Lookup/ldap ディレクトリを開きます。
  2. このディレクトリ内に、次のファイルが見つかります。

    • Server.java
    • Client.java
    • jmx-schema.txt
    • 60jmx-schema.ldif
    • README
  3. テキストエディタでファイルを開きます。
  4. これらのクラスについて、以降のセクションで分析します。

4.4.1 例題クラスの分析

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

4.4.1.1 Server.java

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

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

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

コード 例 4-13 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-13 に、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-12 を参照)。

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

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

4.4.1.2 Client.java

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

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

4.4.1.3 jmx-schema.txt

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

4.4.1.4 60jmx-schema.ldif

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

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

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

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

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

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

  1. 「4.1 初期設定」で起動した LDAP サーバを停止します。
  2. これは使用している LDAP サーバの種類に合わせて実行します。

  3. JMX テクノロジのスキーマをお使いの LDAP サーバの schema ディレクトリにコピーします。
  4. たとえば、Sun ONE Directory Server 5.0 を使用している場合、次のように入力します。

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

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

  5. LDAP サーバを再起動します。
  6. これは使用している LDAP サーバの種類に合わせて実行します。

  7. Server がそのサービス URL を登録するルートを定義します。
  8. Server「4.1 初期設定」で作成したドメインコンポーネントのサフィックス dc=Test のパスを指定する必要があります。

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

  9. Client クラスと Server クラスをコンパイルします。
  10. $ javac -d .Server.java Client.java

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

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

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

  • 次のものを使用した、JRMP トランスポート上の RMI コネクタ
    • 外部ディレクトリなし
    • RMI レジストリ
    • LDAP レジストリ
  • 次のものを使用した、IIOP トランスポート上の RMI コネクタ
    • 外部ディレクトリなし
    • CORBA ネームサービス
    • LDAP レジストリ
  1. Server を起動します。
  2. Server の起動に使用するコマンドは、使用している外部ディレクトリによって異なります。Client を起動する前に、各種のトランスポートおよび外部レジストリを使用して、Server の次のインスタンスの 1 つまたは複数を起動できます。

    1. 外部ディレクトリを使用しない JRMP 上の RMI コネクタ
    2. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .-Ddebug=true \ 
        -Dagent.name=test-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 の実行時の画面出力をより詳細なものにします。
      • 作成されるエージェントの名前は test-server-a です。
      • エージェントが登録されるドメインコンポーネントのサフィックスを示す URL、provider が指定されます。
      • LDAP サーバにアクセスするため、共通名の属性 principal とパスワード credentials が指定されます。
      • サービス URL により、RMI のデフォルトトランスポート JRMP 上で動作する RMI コネクタの選択が指定されます。

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

    3. JRMP 上の RMI コネクタ。外部ディレクトリに RMI レジストリを使用します。
    4. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .-Ddebug=true \ 
        -Dagent.name=test-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 & 
       
      

      このコマンドで、

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

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

    5. JRMP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    6. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .-Ddebug=true \ 
        -Dagent.name=test-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 & 
       
      

      このコマンドで、

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

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

    7. 外部ディレクトリを使用しない IIOP 上の RMI コネクタ
    8. 次のコマンドを入力して Server を起動します。

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

      このコマンドで、

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

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

    9. IIOP 上の RMI コネクタ。外部ディレクトリに CORBA を使用します。
    10. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .-Ddebug=true \ 
        -Dagent.name=test-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 & 
       
      

      このコマンドで、

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

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

    11. IIOP 上の RMI コネクタ。外部ディレクトリに LDAP を使用します。
    12. 次のコマンドを入力して Server を起動します。

       
      $ java -classpath .-Ddebug=true \ 
        -Dagent.name=test-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 & 
       
      

      このコマンドで、

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

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

  3. Client を起動します。
  4. 選択したトランスポートおよび外部ディレクトリを使用して 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* と指定します。

 


目次 | 前の項目 | 次の項目 Java Management Extensions (JMX) テクノロジのチュートリアル
Java Management Extensions (JMX), Java 2 Platform Standard Edition 5.0