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

第 2 章

JMX API の基本要素

この章では、管理対象 Bean、つまり MBeans などの、Java Management Extensions (JMX) API の基本的な概念を紹介します。

MBean は JavaBeanTM に似た管理対象 Java オブジェクトであり、その設計パターンは JMX 仕様の計測レベルの規定に従います。MBean を使用して、デバイス、アプリケーション、または管理が必要なすべてのリソースを表すことができます。MBean は管理インタフェース、すなわち読み込みと書き込みの一方または両方が可能な属性セットと、呼び出し可能な操作セット、および自己記述を開示しています。管理インタフェースは、MBean インスタンスの生存期間を通じて変化しません。また、MBean は、定義済みの特定のイベントが起こった場合に通知を発行します。

JMX 仕様では、標準 MBean動的 MBeanopen MBean、および model MBean という 4 種類の MBean を定義しています。この章の例では、もっとも単純な MBean である標準 MBean について説明します。

Standard MBean

標準 MBean は、Java インタフェース SomethingMBean とそのインタフェースを実装する Java クラス Something を記述することで定義されます。インタフェースのすべてのメソッドは、MBean の属性か操作のいずれかを定義します。デフォルトでは、すべてのメソッドは操作を定義します。属性と操作は、特定の設計パターンに従った簡単なメソッドです。標準 MBean は、開示されたすべての属性と操作のメソッドを一覧にした MBean インタフェースと、このインタフェースを実装し、計測されたリソースに機能を割り当てるクラスから構成されます。

以降のセクションでは、標準 MBean の例と、MBean を管理する簡単な JMX エージェントを詳細に分析します。サンプルコードはディレクトリ work_dir/jmx_examples/Essential/com/example/mbeans. から抜粋しています。

MBean インタフェース

HelloMBean という非常に基本的な MBean インタフェースの例を、コード例 2-1 に示します。

コード例 2-1 MBean インタフェース、HelloMBean の例
 
package com.example.mbeans; 
 
public interface HelloMBean { 
 
    public void sayHello(); 
    public int add(int x, int y); 
 
    public String getName(); 
 
    public int getCacheSize(); 
    public void setCacheSize(int size); 
} 
 

これまでに述べたように、MBean インタフェースは規則により、このインタフェースを実装する Java クラスの名前の後に MBean を加えて名前を構成します。このため、この場合、インタフェースは HelloMBean という名前になります。このインタフェースを実装する Hello クラスについては、セクション「MBean の実装」で説明します。

JMX 仕様によると、MBean インタフェースは、名前と型の指定された読み込み可能で、場合によっては書き込み可能な属性と、MBean が管理するアプリケーションにより呼び出すことが可能な、名前と型の指定された操作から構成されます。コード例 2-1 に示した HelloMBean インタフェースでは、次の 2 つの操作を宣言しています。Java メソッド add() および sayHello() です。

HelloMbean で宣言される 2 つの属性のうち、Name は読み込み専用の文字列で、CacheSize は読み込みと書き込みの両方が可能な整数です。取得メソッドと設定メソッドは、管理対象アプリケーションに属性の値へのアクセスと、場合によっては値の変更を許可するために宣言されます。JMX 仕様に定義されるように、取得メソッドは get から名前が始まり、void を返さないすべての public メソッドです。取得メソッドを使用すると、マネージャーは返されたオブジェクトの型と一致する属性の値を読み込むことができます。設定メソッドは名前が set から始まり、単一のパラメータをとるすべての public メソッドです。設定メソッドを使用すると、マネージャーはパラメータと同じ型の値を属性に新たに書き込むことができます。

次のセクションでは、これらの操作および属性の実装を説明します。

MBean の実装

コード例 2-1 に示した Hello クラスは、HelloMBean を実装します。

コード例 2-1 MBean の実装例、クラス Hello
 
package com.example.mbeans; 
 
public class Hello implements HelloMBean { 
    public void sayHello() { 
        System.out.println("hello, world"); 
    } 
 
    public int add(int x, int y) { 
        return x + y; 
    } 
 
    public String getName() { 
        return this.name; 
    } 
 
 
    public int getCacheSize() { 
        return this.cacheSize; 
    } 
 
    public synchronized void setCacheSize(int size) { 
        this.cacheSize = size; 
 
        System.out.println("Cache size now " + this.cacheSize); 
    } 
 
    private final String name = "Reginald"; 
    private int cacheSize = DEFAULT_CACHE_SIZE; 
    private static final int DEFAULT_CACHE_SIZE = 200; 
} 
 

簡単な Java クラス Hello は、HelloMBean で宣言された操作と属性を定義します。この例からわかるように、sayHello()add() の操作はきわめて簡単ですが、実際の操作は必要に応じて簡単にも、複雑なものにもできます。

Name 属性を取得するメソッドと、cacheSize 属性を取得し設定するメソッドも定義されます。この例では、Name 属性の値は変わりませんが、実際の場面では、管理対象リソースの実行により変わる場合があります。たとえば、属性は稼動時間やメモリーの使用量などの統計を表す場合があります。ここでは、属性は「Reginald」という名前だけです。

setCacheSize メソッドを呼び出すと、cacheSize 属性の値を、宣言されたデフォルトの値 200 から変更できます。実際には、cacheSize 属性を変更する場合は、エントリの破棄や新しいエントリの割り当てなど、ほかの操作を実行しなければなりません。この例では、キャッシュサイズが変更されたことを確認するメッセージのみが出力されますが、println() を呼び出すだけの操作の代わりに、より複雑な操作を定義することができます。

簡単な Hello MBean とそのインタフェースを定義すると、次のセクションに示すように、Hello MBean とインタフェースで表されるリソースを、Hello MBean とインタフェースを使用して管理することができます。

リソースの管理

Java Management Extensions (JMX) テクノロジ概要」で示したように、MBean によってリソースが計測されると、そのリソースの管理は JMX エージェントにより行われます。

JMX エージェントのコアコンポーネントは、MBean を登録する管理対象オブジェクトサーバーである MBean サーバーです (MBean サーバーの実装の詳細は、MBeanServer インタフェースの API ドキュメントを参照)。JMX エージェントには、MBean を管理するための一連のサービスも含まれます。

コード例 2-1 では、Main という基本的な JMX エージェントを示しています。

コード例 2-1 JMX エージェントの作成
 
package com.example.mbeans; 
 
import java.lang.management.*; 
import javax.management.*; 
 
public class Main { 
 
   public static void main(String[] args) throws Exception { 
 
      MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
 
      ObjectName name = new ObjectName("com.example.mbeans:type=Hello"); 
 
      Hello mbean = new Hello(); 
 
      mbs.registerMBean(mbean, name); 
 
      System.out.println("Waiting forever..."); 
      Thread.sleep(Long.MAX_VALUE); 
   } 
} 
 

JMX エージェント Main は、まず java.lang.management.ManagementFactory クラスの getPlatformMBeanServer() メソッドを呼び出して、プラットフォーム上で稼動する任意の MBean サーバーを取得します。プラットフォーム上で稼動中の MBean が存在しない場合、getPlatformMBeanServer() により JMX メソッド MBeanServerFactory.createMBeanServer() が呼び出され、自動的に稼動中の MBean が作成されます。Main で取得される MBeanServer インスタンスは、mbs の名前が付けられます。

次に Main は作成する MBean インスタンスのために、オブジェクト名を定義します。すべての JMX MBean にオブジェクト名が定義される必要があります。オブジェクト名は JMX クラス ObjectName のインスタンスであり、ドメインキープロパティーのリストを必ず含めるなど、JMX 仕様で定義される構文に従う必要があります (この構文の詳細は、ObjectName クラスの API ドキュメントを参照)。Main で定義されるオブジェクト名、name では、ドメインは com.example.mbeans (MBean の例が格納されたパッケージ) です。また、キープロパティーはこのオブジェクトが Hello 型であることを宣言します。

Hello オブジェクトのインスタンス、mbean が作成されます。この Hello オブジェクトは、これ自体がセクション「MBean の実装」で定義された MBean Hello のインスタンスです。

次に Hello オブジェクト mbean は、オブジェクト名 name を使用して MBean server mbs に MBean として登録されます。このために、オブジェクトとオブジェクト名を渡して JMX メソッド MBeanServer.registerMBean() を呼び出します。

Hello MBean を MBean サーバーに登録したあと、Main は管理操作が Hello で実行されるのを待機します。この例の範囲では、これらの管理操作は sayHello()add() を呼び出し、属性値を取得および設定しています。

標準 MBean の例題の実行

クラスの例題を検証したあと、今度は例題を実行します。Java Platform, Standard Edition には JConsole という管理、監視コンソールが付属しており、この例では MBean との対話に使用されています。JConsole は JavaSE_HOME/bin/jconsole にあります。JavaSE_HOME は Java Platform, Standard Edition (Java SE プラットフォーム) がインストールされたディレクトリです。

例を実行するには、次の手順に従うか、README ファイルを参照します。

  1. work_dir/jmx_examples/Essential をまだ開いていない場合は開きます。

    $ cd work_dir/jmx_examples/Essential

  2. Java クラスの例をコンパイルします。

    $ javac com/example/mbeans/*.java

  3. Main アプリケーションを起動します。

    $ java com.example.mbeans.Main

    何かの発生を待機中の Main に関する確認が表示されます。

  4. 同じマシンの別の端末ウィンドウで、JConsole を起動します。

    $ jconsole

    JConsole ツールが開き、接続可能な稼動中の JMX エージェントのリストが表示されます。

  5. 「新規接続」ウィンドウのリストから com.example.mbeans.Main を選択し、「接続」をクリックします。

    プラットフォームの現在のアクティビティーのサマリーが表示されます。

  6. 「MBean」タブをクリックします。

    このパネルに、現在 MBean サーバーに登録されているすべての MBean が表示されます。

  7. 左フレームにある MBean ツリーの com.example.mbeans ノードを展開します。

    Main で作成され、登録された MBean Hello の例が表示されます。Hello をクリックすると、関連する Attributes および Operations ノードが MBean ツリーに表示されます。

  8. MBean ツリーにある Hello MBean ノードをクリックします。

    Hello MBean のメタデータとそれに関連する記述子が表示されます。

  9. MBean ツリーにある Hello MBean の Attributes ノードをクリックします。

    Hello クラスで定義された MBean 属性が表示されます。

  10. CacheSize 属性の値を 150 に変更します

    Main を起動した端末ウィンドウで、この属性の変更を確認が表示されます。

  11. MBean ツリーにある Hello MBean の Operations ノードをクリックします。

    ここで、Hello MBean で宣言された 2 つの操作、sayHello()add() が表示されます。

  12. sayHello」ボタンをクリックして、sayHello() 操作を起動します。

    メソッドが正常に呼び出されたことが JConsole のダイアログボックスに通知され、Main が起動している端末のウィンドウに「hello, world」というメッセージが表示されます。

  13. add() 操作で加算する 2 つの整数を指定し、「add」ボタンをクリックします。

    「JConsole」ダイアログボックスに解答が通知されます。

  14. 「接続」をクリックし、次に「終了」をクリックして、JConsole を終了します。

通知の送信

MBean は状態の変化、検出されたイベント、または問題などを知らせる通知を生成します。

MBean が通知を生成するためには、インタフェース NotificationBroadcaster か、またはそのサブインタフェース NotificationEmitter を実装している必要があります。通知の送信に必要な操作は、クラス javax.management.Notification またはサブクラス (AttributeChangedNotification など) のインスタンスを構築し、それを NotificationBroadcasterSupport.sendNotification に渡すだけです。

すべての通知に発行元があります。発行元は通知を発行した MBean のオブジェクト名です。

すべての通知にはシーケンス番号が割り振られています。順序が重要な意味を持つ場合、および通知が間違った順序で処理される危険性がある場合、この番号を使用して同じソースから到着した通知を並べることができます。シーケンス番号をゼロにしてもかまいませんが、特定の MBean から通知が到着するたびにインクリメントする方が適切です。

標準 MBean がディレクトリ work_dir/jmx_examples/Notification/com/example/mbeans で通知を発行する例を考えてみます。この例は、セクション「標準 MBean」で示した例題と基本的には同じですが、Hello MBean が NotificationBroadcaster インタフェースを実装している点で異なっています。

NotificationBroadcaster インタフェース

前述のように、この例題とセクション「標準 MBean」で示した例題の唯一の違いは、MBean の実装により通知の送信ができるという点です。

コード例 2-1 に示したように、通知は NotificationBroadcaster インタフェースを実装することで起動します。

コード例 2-1 MBean の通知の実装
 
package com.example.mbeans; 
 
import javax.management.*; 
 
public class Hello 
        extends NotificationBroadcasterSupport implements HelloMBean { 
 
    public void sayHello() { 
        System.out.println("hello, world"); 
    } 
 
    public int add(int x, int y) { 
        return x + y; 
    } 
 
    public String getName() { 
        return this.name; 
    } 
 
    public int getCacheSize() { 
        return this.cacheSize; 
    } 
 
    public synchronized void setCacheSize(int size) { 
        int oldSize = this.cacheSize; 
        this.cacheSize = size; 
 
        System.out.println("Cache size now " + this.cacheSize); 
 
        Notification n = 
            new AttributeChangeNotification(this, 
                                            sequenceNumber++, 
                                            System.currentTimeMillis(), 
                                            "CacheSize changed", 
                                            "CacheSize", 
                                            "int", 
                                            oldSize, 
                                            this.cacheSize); 
 
        sendNotification(n); 
    } 
 
    @Override 
    public MBeanNotificationInfo[] getNotificationInfo() { 
        String[] types = new String[] { 
            AttributeChangeNotification.ATTRIBUTE_CHANGE 
        }; 
        String name = AttributeChangeNotification.class.getName(); 
        String description = "An attribute of this MBean has changed"; 
        MBeanNotificationInfo info = 
            new MBeanNotificationInfo(types, name, description); 
        return new MBeanNotificationInfo[] {info}; 
    } 
 
    private final String name = "Reginald"; 
    private int cacheSize = DEFAULT_CACHE_SIZE; 
    private static final int DEFAULT_CACHE_SIZE = 200; 
 
    private long sequenceNumber = 1; 
} 
 

コード例 2-1 に示したとおり、この Hello MBean の実装により NotificationBroadcasterSupport クラスが拡張され、このクラス自体に NotificationEmitter インタフェースが実装されます。

操作と属性の設定方法は以前と同様ですが、唯一変わったのは cacheSize 属性の設定メソッドが oldSize という新しい値を定義する点です。この値は設定操作の前に cacheSize 属性の値を記録します。

通知は、javax.management.Notification を拡張する JMX クラス AttributeChangeNotification のインスタンス n から構築されます。この通知は AttributeChangeNotification にパラメータとして渡される次の情報に基づいて、setCacheSize() メソッドの定義内で構築されます。

  • Hello MBean などの通知の発行元のオブジェクト名。簡単に this と表される
  • シーケンス番号。この例では、ロング名 sequenceNumber が使われ、1 に設定されたあと、1 つずつインクリメントする
  • タイムスタンプ
  • 通知メッセージの内容
  • 変更された属性の名前。この場合は cacheSize
  • 変更された属性の型
  • 古い属性値。この場合は oldSize
  • 新しい属性値。この場合は this.cacheSize

この後、通知 n が NotificationBroadcasterSupport.sendNotification() メソッドに渡されます。

最後に、MBeanNotification が定義され、特定の Java クラスの通知、この場合は AttributeChangeNotification に対して MBean が発行した別の通知インスタンスの特性が説明されます。

MBean インタフェース HelloMBean と JMX エージェント Main は、前出の例で使用されたものと同じです。

MBean の通知の例題の実行

クラスの例題を検証したあと、今度は例題を実行します。この例では、Hello MBean との対話に再度 JConsle を使用します。例を実行する場合は、次の手順に従うか、README ファイルを参照してください。

  1. work_dir/jmx_examples/Notification をまだ開いていない場合は開きます。

    $ cd work_dir/jmx_examples/Notification

  2. Java クラスの例をコンパイルします。

    $ javac com/example/mbeans/*.java

  3. Main アプリケーションを起動します。

    $ java com.example.mbeans.Main

    何かの発生を待機中の Main に関する確認が表示されます。

  4. 同じマシンの別の端末ウィンドウで、JConsole を起動します。

    $ jconsole

    JConsole ツールが開き、接続可能な稼動中の JMX エージェントのリストが表示されます。

  5. 「新規接続」ウィンドウのリストから com.example.mbeans.Main を選択し、「接続」をクリックします。

    プラットフォームの現在のアクティビティーのサマリーが表示されます。

  6. 「MBean」タブをクリックします。

    このパネルに、現在 MBean サーバーに登録されているすべての MBean が表示されます。

  7. 左フレームにある MBean ツリーの com.example.mbeans ノードを展開します。

    Main で作成され、登録された MBean Hello の例が表示されます。Hello をクリックすると、関連する AttributesOperations、および Notifications ノードが MBean ツリーに表示されます。

  8. MBean ツリーにある Hello MBean ノードをクリックします。

    これによって、MBean のメタデータと関連する記述子が表示されます。

  9. MBean ツリーにある Hello MBean の Notifications ノードをクリックします。

    空のパネルが表示されます。

  10. 「Subscribe」ボタンをクリックします。

    現在の受領通知数 (0) が、Notifications ノードラベルに表示されます。

  11. MBean ツリーにある Hello MBean の Attributes ノードをクリックし、CacheSize 属性を 150 に変更します

    Main を起動した端末ウィンドウで、この属性の変更を確認が表示されます。また、Notifications ノードに表示される受領通知数が 1 に変更されています。

  12. MBean ツリーにある Hello MBean の Notifications ノードをふたたびクリックします。

    送信された通知の詳細が表示されます。

  13. 「接続」をクリックし、次に「終了」をクリックして、JConsole を終了します。

MXBean の導入

MXBean は新しいタイプの MBean で、定義済みの型セットだけを参照する MBean のコーディングが簡単にできます。この方法なら、リモートクライアントを含むクライアントは、MBean の型を示すモデル固有のクラスにアクセスしなくても、MBean を利用できます。MXBean は、クライアントに特にバンドル操作の構成を要求することなく、関連する値をバンドルする便利な手法を提供します。

標準 MBean の場合と同様、MXBean を定義するには、SomethingMXBean という Java インタフェースとそのインタフェースを実装する Java クラスを記述します。ただし、標準 MBean とは異なり、MXBean ではその Java クラスを Something と呼ぶ必要はありません。このインタフェース内の各メソッドは、MXBean の属性と操作のいずれかを定義します。そのほか、@MXBean 注釈を使用する場合は、インタフェース名に MXBean 拡張子を付ける代わりに、Java インタフェースに注釈を付けることもできます。

MXBean は、クライアントに特にバンドル操作の構成を要求することなく、MBean と対話しながら関連する値を MBean にバンドルする便利な手法を提供します。MXBean は Java 2 Platform, Standard Edition (J2SE) 5.0 の java.lang.management パッケージに入っています。Java SE 6 プラットフォームでは、java.lang.management で定義された標準セットだけでなく、ユーザー自身の MXBean を定義できます。

MXBean の主な意図は、MXBean インタフェースで参照される java.lang.management.MemoryUsage などの型 (この場合は java.lang.management.MemoryMXBean) を標準型セットにマップすることにあります。その標準型セットは Open Type と呼ばれ、javax.management.openmbean パッケージで定義されます。正確なマッピングの規則は「MXBean の仕様」に記載されていますが、大ざっぱにいえば、intString のような単純な型に変更はなく、MemoryUsage のような複雑な型は CompositeDataSupport 標準型にマップされます。

jmx_examples.zip ファイルをダウンロードして解凍すると、MXBean の操作を説明したサンプルプログラムが work_dir/jmx_examples/MXBean/com/example/mxbeans ディレクトリに作成されます。MXBean のサンプルには、次のファイルが含まれています。

  • QueueSamplerMXBean インタフェース。
  • MXBean インタフェースを実装する QueueSampler クラス。
  • QueueSample Java の型で、MXBean インタフェース内の getQueueSample() メソッドによって返されます。
  • Main、サンプルを設定して実行するプログラム。

MXBean のサンプルには、次のアクションが含まれています。

  • type Queue<String> のリソースを管理する、単純な MXBean を定義する。
  • 呼び出されるとキューのスナップショットを作成する MXBean の取得メソッド getQueueSample を宣言し、次の値をバンドルする Java クラス QueueSample を返す。
  • スナップショットが作成された時間。
  • キューのサイズ。
  • 指定された時間のキューの先頭。
  • MBean サーバーに MXBean を登録する。

QueueSamplerMXBean インタフェース

コード例 2-1 は、QueueSamplerMXBean インタフェースのサンプルコードを示しています。

コード例 2-1 QueueSamplerMXBean インタフェース
 
package com.example.mxbeans; 
 
public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 
} 
 

この例からわかるように、MXBean インタフェースの宣言は標準 MBean の宣言とまったく同じです。QueueSamplerMXBean インタフェースでは、getQueueSampleclearQueue という 2 つの操作を宣言しています。

QueueSampler クラス

QueueSampler クラスは、コード例 2-1に示すように、QueueSamplerMXBean インタフェースを実装しています。

コード例 2-1 QueueSampler クラス
package com.example.mxbeans; 
 
import java.util.Date; 
import java.util.Queue; 
 
public class QueueSampler implements QueueSamplerMXBean { 
     
    private Queue<String> queue; 
     
    public QueueSampler(Queue<String> queue) { 
       this.queue = queue; 
    } 
     
    public QueueSample getQueueSample() { 
        synchronized (queue) { 
            return new QueueSample(new Date(), queue.size(), queue.peek()); 
        } 
    } 
     
    public void clearQueue() { 
        synchronized (queue) { 
            queue.clear(); 
        } 
    } 
} 
 

MXBean インタフェースで宣言された MXBean 操作の getQueueSample() および clearQueue() は、QueueSampler で定義されます。getQueueSample() 操作は単純に、QueueSample Java 型 (java.util.Queue メソッドの peek() および size() によって返された値を使用して作成) のインスタンスと java.util.Date のインスタンスを返します。

QueueSample クラス

QueueSampler によって返された QueueSample インスタンスは、コード例 2-1 に示した QueueSample クラスで定義されます。

コード例 2-1 QueueSample クラス
package com.example.mxbeans; 
 
import java.beans.ConstructorProperties; 
import java.util.Date; 
 
public class QueueSample { 
     
    private final Date date; 
    private final int size; 
    private final String head; 
     
    @ConstructorProperties({"date", "size", "head"}) 
    public QueueSample(Date date, int size, String head) { 
        this.date = date; 
        this.size = size; 
        this.head = head; 
    } 
     
    public Date getDate() { 
        return date; 
    } 
     
    public int getSize() { 
        return size; 
    } 
     
    public String getHead() { 
        return head; 
    } 
} 
 

QueueSample クラスでは、MXBean フレームワークが QueueSample の取得メソッドをすべて呼び出して、指定されたインスタンスを CompositeData に変換し、@ConstructorProperties 注釈を使用して、CompositeData から QueueSample インスタンスを再構築します。

MXBean の作成と MBean サーバーへの登録

MXBean インタフェースとこれを実装するクラス、および返される Java 型を定義したら、次は MXBean を作成して MBean サーバーに登録する必要があります。これらのアクションは、サンプルクラス Main によって行われます。

コード例 2-1 MXBean の Main クラスの例
package com.example.mxbeans; 
 
import java.lang.management.ManagementFactory; 
import java.util.Queue; 
import java.util.concurrent.ArrayBlockingQueue; 
import javax.management.MBeanServer; 
import javax.management.ObjectName; 
 
public class Main { 
 
    public static void main(String[] args) throws Exception { 
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
         
        ObjectName name = 
                new ObjectName("com.example.mxbeans:type=QueueSampler"); 
         
        Queue<String> queue = new ArrayBlockingQueue<String>(10); 
        queue.add("Request-1"); 
        queue.add("Request-2"); 
        queue.add("Request-3"); 
        QueueSampler mxbean = new QueueSampler(queue); 
         
        mbs.registerMBean(mxbean, name); 
         
        System.out.println("Waiting..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 
} 
 

Main クラスは、プラットフォーム MBean サーバーを取得して、MXBean QueueSampler のオブジェクト名を作成し、QueueSampler MXBean の Queue インスタンスを作成して処理します。次に、この Queue インスタンスを、新規作成された QueueSampler MXBean に送ります。これで標準 MBean とまったく同じように、MXBean が MBean サーバーに登録されます。

MXBean の例題の実行

例を実行するには、次の手順に従うか、README ファイルを参照します。

  1. work_dir/jmx_examples/MXBean をまだ開いていない場合は開きます。

    $ cd work_dir/jmx_examples/MXBean

  2. Java クラスの例をコンパイルします。

    $ javac com/example/mxbeans/*.java

  3. Main アプリケーションを起動します。

    $ java com.example.mxbeans.Main

    何かの発生を待機中の Main に関する確認が表示されます。

  4. 同じマシンの別の端末ウィンドウで、JConsole を起動します。

    $ jconsole

    JConsole ツールが開き、接続可能な稼動中の JMX エージェントのリストが表示されます。

  5. 「新規接続」ウィンドウのリストから com.example.mxbeans.Main を選択し、「接続」をクリックします。

    プラットフォームの現在のアクティビティーのサマリーが表示されます。

  6. 「MBean」タブをクリックします。

    このパネルに、現在 MBean サーバーに登録されているすべての MBean が表示されます。

  7. 左フレームにある MBean ツリーの com.example.mxbeans ノードを展開します。

    Main で作成され、登録された MBean QueueSampler の例が表示されます。QueueSampler をクリックすると、関連する Attributes および Operations ノードが MBean ツリーに表示されます。

  8. Attributes ノードを選択します。

    右ペインに QueueSample 属性とその javax.management.openmbean.CompositeDataSupport の値が表示されます。

  9. CompositeDataSupport 値をダブルクリックします。

    MXBean フレームワークが QueueSample インスタンスを CompositeData に変換したため、QueueSample の値である datehead、および size が表示されます。QueueSampler を MXBean ではなく標準 MBean として定義した場合、QueueSample クラスはそのクラスパスには存在しないので JConsole からは見つかりません。QueueSampler が標準 MBean の場合、QueueSample 属性値を抽出すると ClassNotFoundException が返されます。このように、JConsole のように汎用的な JMX クライアントで JMX エージェントに接続するときに MXBean を使用すると便利です。

  10. Operations ノードを選択します。

    clearQueue 操作を呼び出すボタンが表示されます。

  11. clearQueue」ボタンをクリックします。

    メソッドの呼び出しに成功したことが通知されます。

  12. Attributes ノードをもう一度選択し、CompositeDataSupport 値をダブルクリックします。

    これでキューがリセットされます。

  13. 「接続」をクリックし、次に「終了」をクリックして、JConsole を終了します。

この例では、JConsole が JMX クライアントとして使用されましたが、JMX クライアントの自作プログラムから MXBean にアクセスする場合は次の 2 つの方法のどちらかで行います。

  • 一般的には次のコードを使用する。
コード例 2-1 MXBean に直接アクセスする
 
MBeanServer mbs = ...whatever...; 
ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler"); 
CompositeData queueSample = (CompositeData) mbs.getAttribute(name,  
                             "QueueSample"); 
int size = (Integer) queueSample.get("size"); 
  • プロキシ経由。次のコードを使用する。
コード例 2-2 プロキシ経由で MXBean にアクセスする
 
MBeanServer mbs = ...whatever...; 
ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler"); 
QueueSamplerMXBean proxy = JMX.newMXBeanProxy(mbs, name,  
                                              QueueSamplerMXBean.class); 
QueueSample queueSample = proxy.getQueueSample(); 
int size = queueSample.getSize(); 

コード例 2-2 では、newMXBeanProxy メソッドを使用して MXBean プロキシを作成しています。newMBeanProxy という等価のメソッドがあるのは、ほかの型の MBean で使用するプロキシを作成するためです。newMBeanProxy および newMXBeanProxy メソッドの使用法はまったく同じです。

MBean 記述子

記述子によって、MBean に関する追加情報を管理クライアントに提供できます。たとえば、MBean 属性に関する記述子で計測単位や最大値と最小値を示す場合もあります。Java SE 6 の時点で、記述子は JMX API に含まれており、どの MBean でも使用可能です。

記述子は、任意のメタデータを MBean に追加する場合に便利です。記述子は JMX API に必ずありますが、Java SE 6 までは Model MBean と別に使用することはできません。

MBean*Info クラス (MBeanInfoMBeanAttributeInfo など) のほとんどのコンストラクタの場合、それぞれに共通するパラメータと追加パラメータ javax.management.Descriptor を持つ並列コンストラクタが存在します。OpenMBean*InfoSupport の場合も同様です。MBean*Info および OpenMBean*InfoSupport クラスには、getDescriptor() メソッドが含まれています。

Open MBeans は、OpenMBeanParameterInfo および OpenMBeanAttributeInfoのメソッド getDefaultValue()getLegalValues()getMaxValue()getMinValue() から、デフォルトに関する情報と有効な値を返します。今回、この情報が対応する記述子にも含まれるようになりました。また、ほかの MBean 型も自身の記述子の情報を返すことができます。

jmx_examples.zip ファイルをダウンロードして解凍すると、MBean 記述子を説明したサンプルプログラムが work_dir/jmx_examples/Descriptors/com/example/mxbeans ディレクトリに作成されます。MBean 記述子のサンプルには、次のファイルが含まれています。

  • Author。MBean インタフェースの著者名を示す注釈。
  • DisplayName。MBean インタフェースのメソッドの表示名を示す注釈。
  • Main、サンプルを設定して実行するプログラム。
  • QueueSamplerMXBean インタフェース。
  • MXBean インタフェースを実装する QueueSampler クラス。
  • QueueSample Java の型で、MXBean インタフェース内の getQueueSample() メソッドによって返されます。
  • Version。MBean インタフェースの現在のバージョンを示す注釈。

この例に示す QueueSampler MXBean は、第 2 章「MXBean の導入」に示した MXBean の例と基本的に同じアクションを実行していますが、MBean 記述子が追加されている点が異なります。この例は、DescriptorKey メタ注釈を使用することで、標準 MBean (または MXBean) インタフェース内の注釈によって標準 MBean (または MXBean) の記述子に新しい記述子を追加する方法を示しています。

DescriptorKey 注釈

新しい注釈 DescriptorKey を使用することで、標準 MBean (または MXBean) インタフェース内の注釈によって標準 MBean (または MXBean) の記述子に情報を追加できます。これによって、ツールで既存の管理モデルから標準 MBean を生成し、そのモデルからの情報を別のファイルではなく生成された MBean インタフェースに含めることができます。

コード例 2-1 は、Author 注釈の定義を示しています。

コード例 2-1 Author 注釈
 
package com.example.mxbeans; 
 
import java.lang.annotation.Documented; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import javax.management.DescriptorKey; 
 
@Documented 
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Author { 
    @DescriptorKey("author") 
    String value(); 
} 

この注釈は、MBean インタフェースの作成者の名前を提供します。新しいフィールド author は、@Author 注釈によって定義された値を持つ MBeanInfo 記述子に追加されます。ファイル Version および DisplayName は、これらの名前の注釈を、前述の Author の場合とまったく同様に定義します。Version および DisplayName@DescriptorKey 値は、それぞれ “version” および “displayname” です。

Version の場合、新しいフィールド version@Version 注釈によって定義された値を持つ MBeanInfo 記述子に追加されます。

DisplayName の場合、新しいフィールド displayName は、注釈を付けられたメソッドが取得メソッド/設定メソッドと操作のどちらであるかに応じて、それぞれ @DisplayName 注釈によって定義された値を持つ MBeanAttributeInfo 記述子または MBeanOperationInfo 記述子に追加されます。

MBean 記述子の使用

次の例で使用されている QueueSamplerMXBean インタフェースは、MBean 記述子を実装してその情報の一部を公開する範囲にかぎり、MXBean の例で使用されているインタフェースとはわずかに異なります。

コード例 2-1 記述子を使用した QueueSamplerMXBean。
 
package com.example.mxbeans; 
 
@Author("Mr Bean") 
@Version("1.0") 
public interface QueueSamplerMXBean { 
    @DisplayName("GETTER: QueueSample") 
    public QueueSample getQueueSample(); 
    @DisplayName("OPERATION: clearQueue") 
    public void clearQueue(); 
} 
 

これで @Author 注釈は Mr. Bean@Version 注釈は 1.0@DisplayName は属性 QueueSample と操作 clearQueue のどちらかの名前に設定されます。

MBean 記述子の例題の実行

例を実行するには、次の手順に従うか、README ファイルを参照します。

  1. work_dir/jmx_examples/Descriptors をまだ開いていない場合は開きます。

    $ cd work_dir/jmx_examples/Descriptors

  2. Java クラスの例をコンパイルします。

    $ javac com/example/mxbeans/*.java

  3. Main アプリケーションを起動します。

    $ java com.example.mxbeans.Main

    何かの発生を待機中の Main に関する確認が表示されます。

  4. 同じマシンの別の端末ウィンドウで、JConsole を起動します。

    $ jconsole

    JConsole ツールが開き、接続可能な稼動中の JMX エージェントのリストが表示されます。

  5. 「新規接続」ウィンドウのリストから com.example.mxbeans.Main を選択し、「接続」をクリックします。

    プラットフォームの現在のアクティビティーのサマリーが表示されます。

  6. 「MBean」タブをクリックします。

    このパネルに、現在 MBean サーバーに登録されているすべての MBean が表示されます。

  7. 左フレームにある MBean ツリーの com.example.mxbeans ノードを展開します。

    Main で作成され、登録された MBean QueueSampler の例が表示されます。QueueSampler をクリックすると、関連する Attributes および Operations ノードが MBean ツリーに表示されます。また、MBeanInfo 記述子表には author および version フィールドも表示されます。

  8. QueueSampler MBean ノードの下にある Attributes および Operations ノードを展開します。

    Attributes と Operations が個別に表示されます。

  9. QueueSample ノードを選択します。

    MBeanAttributeInfo 記述子表に displayName フィールドが表示されます。

  10. clearQueue ノードを選択します。

    MBeanOperationInfo 記述子表に displayName フィールドが表示されます。

  11. 「接続」をクリックし、次に「終了」をクリックして、JConsole を終了します。


目次 | 前へ | 次へ


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