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を起動します。
$ jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
- 「新規接続」ウィンドウのリストから
com.example.mbeans.Main
を選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
- 「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
- 左フレームにあるMBeanツリーの
com.example.mbeans
ノードを展開します。Main
で作成され、登録されたMBeanHello
の例が表示されます。Hello
をクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。 - MBeanツリー内の
Hello
MBeanノードをクリックしてHello
MBeanのメタデータとそれに関連する記述子を表示します。 - MBeanツリーにある
Hello
MBeanのAttributes
ノードをクリックします。Hello
クラスで定義されたMBean属性が表示されます。 CacheSize
属性の値を150に変更します。Main
を起動した端末ウィンドウで、この属性の変更を確認が表示されます。- MBeanツリーにあるHello MBeanの
Operations
ノードをクリックします。ここで、
Hello
MBeanで宣言された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()
メソッドの定義内で構築されます。
Hello
MBeanなどの通知の発行元のオブジェクト名。簡単に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を起動します。
$ jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
-
「新規接続」ウィンドウのリストから
com.example.mbeans.Main
を選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
-
「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
-
左フレームにあるMBeanツリーの
com.example.mbeans
ノードを展開します。Main
で作成され、登録されたMBeanHello
の例が表示されます。Hello
をクリックすると、関連するAttributes
、Operations
、およびNotifications
ノードがMBeanツリーに表示されます。 -
MBeanツリーにある
Hello
MBeanノードをクリックします。これによって、MBeanのメタデータと関連する記述子が表示されます。
-
MBeanツリーにあるHello MBeanの
Notifications
ノードをクリックします。空のパネルが表示されます。
-
「Subscribe」ボタンをクリックします。
現在の受領通知数(0)が、Notificationsノード・ラベルに表示されます。
-
MBeanツリーにある
Hello
MBeanのAttributes
ノードをクリックし、CacheSize
属性を150に変更します。Main
を起動した端末ウィンドウで、この属性の変更を確認が表示されます。また、Notificationsノードに表示される受領通知数が1に変更されています。 -
MBeanツリーにある
Hello
MBeanの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
クラス。 QueueSample
Javaの型で、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を起動します。
$ jconsole
JConsoleツールが開き、接続可能な稼動中の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
クラス。 QueueSample
Javaの型で、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を起動します。
$ jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
-
「新規接続」ウィンドウのリストから
com.example.mxbeans.Main
を選択し、「接続」をクリックします。プラットフォームの現在のアクティビティのサマリーが表示されます。
-
「MBean」タブをクリックします。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
-
左フレームにあるMBeanツリーの
com.example.mxbeans
ノードを展開します。Mainで作成され、登録されたMBean
QueueSampler
の例が表示されます。QueueSampler
をクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。フィールドauthor
およびversion
もMBeanInfo
記述子表に表示されます。 -
QueueSampler
MBeanノードの下にあるAttributes
およびOperations
ノードを展開します。AttributesとOperationsが個別に表示されます。
-
QueueSample
ノードを選択します。MBeanAttributeInfo
記述子表にdisplayName
フィールドが表示されます。 -
clearQueue
ノードを選択します。MBeanOperationInfo
記述子表にdisplayName
フィールドが表示されます。 -
「接続」をクリックし、次に「終了」をクリックして、JConsoleを終了します。