10 JMX APIの基本要素
この章では、Java Management Extensions (JMX) APIのコア・コンポーネントである管理対象Bean (MBean)について説明します。
MBeanはJavaBeanに似た管理対象Javaオブジェクトであり、その設計パターンはJMX仕様の計測レベルの規定に従います。MBeanは、管理対象となるデバイス、アプリケーションまたは任意のリソースを表示できます。MBeanは管理インタフェース、すなわち読込みと書込みの一方または両方が可能な属性セットと、呼出し可能な操作セット、および自己記述を開示しています。管理インタフェースは、MBeanインスタンスの生存期間を通じて変化しません。また、MBeanは、定義済みの特定のイベントが起こった場合に通知を発行します。
JMX仕様では、標準MBean、動的MBean、open MBean、およびmodel MBeanという4種類のMBeanを定義しています。このチュートリアルの例では、もっとも単純なMBeanである標準MBeanについて説明します。
標準MBean
標準MBeanは、JavaインタフェースSomethingMBeanとそのインタフェースを実装するJavaクラスSomethingを記述することで定義できます。インタフェースのすべてのメソッドは、MBeanの属性か操作のいずれかを定義します。デフォルトでは、すべてのメソッドは操作を定義します。属性と操作は、特定の設計パターンに従った簡単なメソッドです。標準MBeanは、開示されたすべての属性と操作のメソッドを一覧にしたMBeanインタフェースと、このインタフェースを実装し、計測されたリソースに機能を割り当てるクラスから構成されます。
                  
以降のセクションでは、標準MBeanの例と、MBeanを管理する簡単なJMXエージェントについて説明します。コード・サンプルはJMXの基本要素にあります。例をディレクトリwork_dir/jmx_examples/Essential/com/example/mbeansから実行できます。
MBeanインタフェース
HelloMBeanという基本的なMBeanインタフェースの例を、次のコード例に示します。
                     
コード例10-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 MBeanインタフェース、HelloMBeanに示したHelloMBeanインタフェースでは、10つの操作(Javaメソッドadd()とsayHello())を宣言しています。
                        
HelloMbeanで宣言される2つの属性のうち、Nameは読込み専用の文字列で、CacheSizeは読み込みと書込みの両方が可能な整数です。取得メソッドと設定メソッドは、管理対象アプリケーションに属性の値へのアクセスと、場合によっては値の変更を許可するために宣言されます。JMX仕様に定義されるように、取得メソッドはgetから名前が始まり、voidを返さないすべてのpublicメソッドです。取得メソッドを使用すると、マネージャは返されたオブジェクトの型と一致する属性の値を読み込むことができます。設定メソッドは名前がsetから始まり、単一のパラメータをとるすべてのpublicメソッドです。設定メソッドを使用すると、マネージャはパラメータと同じ型の値を属性に新たに書き込むことができます。
                        
次のセクションでは、これらの操作および属性の実装を説明します。
MBeanの実装
次のコード例に示すHelloクラスは、HelloMBeanを実装します。
                     
コード例10-2 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; 
} 
 
例10-2では、JavaクラスHelloは、HelloMBeanで宣言された操作と属性を定義します。この例からわかるように、例 sayHello()とadd()の操作はきわめて簡単ですが、実際の操作は必要に応じて簡単にも、複雑なものにもできます。
                        
Name属性を取得するメソッドと、cacheSize属性を取得し設定するメソッドも定義されます。この例では、Name属性の値は変わりませんが、実際の場面では、管理対象リソースの実行により変わる場合があります。たとえば、属性は稼動時間やメモリーの使用量などの統計を表す場合があります。ここでは、属性は「Reginald」という名前だけです。
                        
setCacheSizeメソッドを呼び出すと、cacheSize属性の値を、宣言されたデフォルトの値200から変更できます。実際には、cacheSize属性を変更する場合は、エントリの破棄や新しいエントリの割り当てなど、ほかの操作を実行しなければなりません。この例では、キャッシュ・サイズが変更されたことを確認するメッセージのみが出力されますが、println()を呼び出す操作のかわりに、より複雑な操作を定義できます。
                        
Hello MBeanとそのインタフェースを定義すると、次のセクションに示すように、Hello MBeanとインタフェースで表されるリソースを、Hello MBeanとインタフェースを使用して管理できます。
                        
リソースの管理
Java Management Extensions Technology User's Guideに説明されているように、MBeanによってリソースが計測された後は、そのリソースの管理はJMXエージェントにより実行されます。
JMXエージェントのコア・コンポーネントはMBeanサーバーです。MBeanサーバーは、MBeanが登録されている管理オブジェクト・サーバーのことです。MBeanサーバー実装の詳細は、MBeanServerインタフェースのAPIドキュメントを参照してください。JMXエージェントには、MBeanを管理するための一連のサービスも含まれます。次のコード例は、Mainという名前の基本JMXエージェントを示しています。
                     
コード例10-3 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); 
   } 
} 
 
例10-3では、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プラットフォーム)がインストールされたディレクトリです。
                     
例題を実行するには:
- 
                           
「JMXの基本要素」の項に含まれているソース・コードをコピーし、対応するファイルを
work_dir/jmx_examples/Essentialディレクトリに作成します。 - Javaクラスの例をコンパイルします。 
                           
$ javac com/example/mbeans/*.java Mainアプリケーションを起動します。$ java com.example.mbeans.Main何かの発生を待機中の
Mainに関する確認が表示されます。- 同じマシンの別の端末ウィンドウで、JConsoleを起動します。 
                           
$ jconsoleJConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
 - 「新規接続」ウィンドウのリストから
com.example.mbeans.Mainを選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
 - 「MBean」タブをクリックします。 
                           
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
 - 左フレームにあるMBeanツリーの
com.example.mbeansノードを展開します。Mainで作成され、登録されたMBeanHelloの例が表示されます。Helloをクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。 - MBeanツリー内の
HelloMBeanノードをクリックしてHelloMBeanのメタデータとそれに関連する記述子を表示します。 - MBeanツリーにある
HelloMBeanのAttributesノードをクリックします。Helloクラスで定義されたMBean属性が表示されます。 CacheSize属性の値を150に変更します。Mainを起動した端末ウィンドウで、この属性の変更を確認が表示されます。- MBeanツリーにあるHello MBeanの
Operationsノードをクリックします。ここで、
HelloMBeanで宣言された2つの操作、sayHello()とadd()が表示されます。 - 「
sayHello」ボタンをクリックして、sayHello()操作を起動します。メソッドが正常に呼び出されたことがJConsoleのダイアログ・ボックスに通知され、
Mainが起動している端末のウィンドウに「hello, world」というメッセージが表示されます。 add()操作で加算する2つの整数を指定し、「add」ボタンをクリックします。「JConsole」ダイアログ・ボックスに解答が通知されます。
- 「接続」をクリックし、次に「終了」をクリックして、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の実装により通知の送信ができるという点です。次のコード例に示すように、通知はNotificationBroadcasterインタフェースを実装することで起動します。
                     
コード例10-4 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; 
} 
 
コード例10-4 MBeanの通知の実装に示したように、このHello MBeanの実装によりNotificationBroadcasterSupportクラスが拡張され、このクラス自体にNotificationEmitterインタフェースが実装されます。
                        
操作と属性の設定方法は以前と同様ですが、唯一変わったのはcacheSize属性の設定メソッドがoldSizeという新しい値を定義する点です。この値は設定操作の前にcacheSize属性の値を記録します。
                        
通知は、javax.management.Notificationを拡張するJMXクラスAttributeChangeNotificationのインスタンスnから構築されます。この通知はAttributeChangeNotificationにパラメータとして渡される次の情報に基づいて、setCacheSize()メソッドの定義内で構築されます。
                        
HelloMBeanなどの通知の発行元のオブジェクト名。簡単にthisと表される- シーケンス番号。この例では、ロング名
sequenceNumberが使われ、1に設定されたあと、1つずつインクリメントする - タイムスタンプ
 - 通知メッセージの内容
 - 変更された属性の名前。この場合は
cacheSize - 変更された属性の型
 - 古い属性値。この場合は
oldSize - 新しい属性値。この場合は
this.cacheSize 
この後、通知nがNotificationBroadcasterSupport.sendNotification()メソッドに渡されます。
                        
最後に、MBeanNotificationが定義され、特定のJavaクラスの通知、この場合はAttributeChangeNotificationに対してMBeanが発行した別の通知インスタンスの特性が説明されます。
                        
MBeanインタフェースHelloMBeanとJMXエージェントMainは、前出の例で使用されたものと同じです。
                        
MBeanの通知の例題の実行
クラスの例題を検証したあと、今度は例題を実行します。この例では、JConsoleを使用してHello MBeanと対話します。この例題を実行するには:
                     
- 
                           
「JMX MBeanの通知」の項に含まれるソース・コード例を
work_dir/jmx_examples/Notificationにコピーします。 - 
                           
Javaクラスの例をコンパイルします。
$ javac com/example/mbeans/*.java - 
                           
Mainアプリケーションを起動します。$ java com.example.mbeans.Main何かの発生を待機中の
Mainに関する確認が表示されます。 - 
                           
同じマシンの別の端末ウィンドウで、JConsoleを起動します。
$ jconsoleJConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
 - 
                           
「新規接続」ウィンドウのリストから
com.example.mbeans.Mainを選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
 - 
                           
「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
 - 
                           
左フレームにあるMBeanツリーの
com.example.mbeansノードを展開します。Mainで作成され、登録されたMBeanHelloの例が表示されます。Helloをクリックすると、関連するAttributes、Operations、およびNotificationsノードがMBeanツリーに表示されます。 - 
                           
MBeanツリーにある
HelloMBeanノードをクリックします。これによって、MBeanのメタデータと関連する記述子が表示されます。
 - 
                           
MBeanツリーにあるHello MBeanの
Notificationsノードをクリックします。空のパネルが表示されます。
 - 
                           
「Subscribe」ボタンをクリックします。
現在の受領通知数(0)が、Notificationsノード・ラベルに表示されます。
 - 
                           
MBeanツリーにある
HelloMBeanのAttributesノードをクリックし、CacheSize属性を150に変更します。Mainを起動した端末ウィンドウで、この属性の変更を確認が表示されます。また、Notificationsノードに表示される受領通知数が1に変更されています。 - 
                           
MBeanツリーにある
HelloMBeanのNotificationsノードをふたたびクリックします。送信された通知の詳細が表示されます。
 - 「接続」をクリックし、次に「終了」をクリックして、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の仕様」に記載されていますが、大ざっぱにいえば、intやStringのような単純な型に変更はなく、MemoryUsageのような複雑な型はCompositeDataSupport標準型にマップされます。
                  
MXBeanの操作は、MXBeanのサンプル・プログラムで示されます。MXBeanのサンプルには、次のファイルが含まれています。
QueueSamplerMXBeanインタフェース。- MXBeanインタフェースを実装する
QueueSamplerクラス。 QueueSampleJavaの型で、MXBeanインタフェース内のgetQueueSample()メソッドによって返されます。Main、サンプルを設定して実行するプログラム。
MXBeanのサンプルには、次のアクションが含まれています。
type Queue<String>のリソースを管理する、単純なMXBeanを定義する。- 呼び出されるとキューのスナップショットを作成するMXBeanの取得メソッド
getQueueSampleを宣言し、次の値をバンドルするJavaクラスQueueSampleを返す。- スナップショットが作成された時間。
 - キューのサイズ。
 - 指定された時間のキューの先頭。
 
 - MBeanサーバーにMXBeanを登録する。
 
QueueSamplerMXBeanインタフェース
次のコード例に、サンプルのQueueSamplerMXBeanインタフェースのソース・コードを示します。
                     
コード例10-5 QueueSamplerMXBeanインタフェース
 
package com.example.mxbeans; 
 
public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 
} 
 
この例からわかるように、MXBeanインタフェースの宣言は標準MBeanの宣言とまったく同じです。QueueSamplerMXBeanインタフェースでは、getQueueSampleとclearQueueという2つの操作を宣言しています。
                        
QueueSamplerクラス
QueueSamplerクラスは、次のコード例に示すように、QueueSamplerMXBeanインタフェースを実装しています。
                     
コード例10-6 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インスタンスは、次のコード例に示すQueueSampleクラスで定義されます。
                     
コード例10-7 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によって実行されます。
                     
コード例10-8 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の例題の実行
MXBeanの例題を実行するには:
- 
                           
「MXBean」の項に含まれているソース・コードを
work_dir/jmx_examples/MXBeanにコピーします。 - 
                           
Javaクラスの例をコンパイルします。
$ javac com/example/mxbeans/*.java - 
                           
Mainアプリケーションを起動します。$ java com.example.mxbeans.Main何かの発生を待機中の
Mainに関する確認が表示されます。 - 
                           
同じマシンの別の端末ウィンドウで、JConsoleを起動します。
$ jconsoleJConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
 - 
                           
「新規接続」ウィンドウのリストから
com.example.mxbeans.Mainを選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
 - 
                           
「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
 - 
                           
左フレームにあるMBeanツリーの
com.example.mxbeansノードを展開します。Mainで作成され、登録されたMBean
QueueSamplerの例が表示されます。QueueSamplerをクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。 - 
                           
Attributesノードを選択します。右ペインに
QueueSample属性とそのjavax.management.openmbean.CompositeDataSupportの値が表示されます。 - 
                           
CompositeDataSupport値をダブルクリックします。MXBeanフレームワークが
QueueSampleインスタンスをCompositeDataに変換したため、QueueSampleの値であるdate、head、およびsizeが表示されます。QueueSamplerをMXBeanではなく標準MBeanとして定義した場合、QueueSampleクラスはそのクラス・パスには存在しないのでJConsoleからは見つかりません。QueueSamplerが標準MBeanの場合、QueueSample属性値を抽出するとClassNotFoundExceptionが返されます。このように、JConsoleのように汎用的なJMXクライアントでJMXエージェントに接続するときにMXBeanを使用すると便利です。 - 
                           
Operationsノードを選択します。
clearQueue操作を呼び出すボタンが表示されます。 - 
                           
「clearQueue」ボタンをクリックします。
メソッドの呼出しに成功したことが通知されます。
 - 
                           
Attributesノードをもう一度選択し、
CompositeDataSupport値をダブルクリックします。これでキューがリセットされます。
 - 
                           
「接続」をクリックし、次に「終了」をクリックして、JConsoleを終了します。
 
この例では、JConsoleがJMXクライアントとして使用されましたが、JMXクライアントの自作プログラムからMXBeanにアクセスする場合は次の2つの方法のどちらかで行います。
- 
                           
一般的には次のコードを使用します。
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"); - 
                           
プロキシ経由では次のコードを使用します。
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();このコードでは、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クラス(MBeanInfo、MBeanAttributeInfoなど)のほとんどのコンストラクタの場合、それぞれに共通するパラメータと追加パラメータ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クラス。 QueueSampleJavaの型で、MXBeanインタフェース内のgetQueueSample()メソッドによって返されます。Version。MBeanインタフェースの現在のバージョンを示す注釈。
この例に示すQueueSampler MXBeanは、MXBeanの導入に示したMXBeanの例と基本的に同じアクションを実行していますが、MBean記述子が追加されている点が異なります。この例は、DescriptorKeyメタ注釈を使用することで、標準MBean (またはMXBean)インタフェース内の注釈によって標準MBean (またはMXBean)の記述子に新しい記述子を追加する方法を示しています。
                  
DescriptorKey注釈
注釈DescriptorKeyを使用することで、標準MBeanまたはMXBeanインタフェース内の注釈によって標準MBeanまたはMXBeanの記述子に情報を追加できます。これによって、ツールで既存の管理モデルから標準MBeanを生成し、そのモデルからの情報を別のファイルではなく生成されたMBeanインタフェースに含めることができます。次のコード例は、注釈Authorの定義を示しています。
                     
コード例10-9 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インタフェースは、MXBeansの例で使用されているインタフェースとは多少異なります。これは、MBean記述子を実装し、その情報の一部を公開します。
                     
コード例10-10 記述子を使用した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記述子の例題の実行
例題を実行するには:
- 
                           
「MBean記述子」の項に含まれているソース・コードを
work_dir/jmx_examples/MXBeanにコピーします。 - 
                           
Javaクラスの例をコンパイルします。
$ javac com/example/mxbeans/*.java - 
                           
Mainアプリケーションを起動します。$ java com.example.mxbeans.Main何かの発生を待機中の
Mainに関する確認が表示されます。 - 
                           
同じマシンの別の端末ウィンドウで、JConsoleを起動します。
$ jconsoleJConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
 - 
                           
「新規接続」ウィンドウのリストから
com.example.mxbeans.Mainを選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
 - 
                           
「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
 - 
                           
左フレームにあるMBeanツリーの
com.example.mxbeansノードを展開します。Mainで作成され、登録されたMBean
QueueSamplerの例が表示されます。QueueSamplerをクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。フィールドauthorおよびversionもMBeanInfo記述子表に表示されます。 - 
                           
QueueSamplerMBeanノードの下にあるAttributesおよびOperationsノードを展開します。AttributesとOperationsが個別に表示されます。
 - 
                           
QueueSampleノードを選択します。MBeanAttributeInfo記述子表にdisplayNameフィールドが表示されます。 - 
                           
clearQueueノードを選択します。MBeanOperationInfo記述子表にdisplayNameフィールドが表示されます。 - 
                           
「接続」をクリックし、次に「終了」をクリックして、JConsoleを終了します。