目次|前|次 | Java Management Extensions (JMX)テクノロジのチュートリアル |
この章では、管理対象Bean、つまりMBeansなどの、Java Management Extensions (JMX) APIの基本的な概念を紹介します。
MBeanはJavaBeanTMに似た管理対象Javaオブジェクトであり、その設計パターンはJMX仕様の計測レベルの規定に従います。MBeanを使用して、デバイス、アプリケーション、または管理が必要なすべてのリソースを表すことができます。MBeanは管理インタフェース、すなわち読み込みと書込みの一方または両方が可能な属性セットと、呼出し可能な操作セット、および自己記述を開示しています。管理インタフェースは、MBeanインスタンスの生存期間を通じて変化しません。また、MBeanは、定義済みの特定のイベントが起こった場合に通知を発行します。
JMX仕様では、標準MBean、動的MBean、open MBean、およびmodel MBeanという4種類のMBeanを定義しています。この章の例では、もっとも単純なMBeanである標準MBeanについて説明します。
標準MBeanは、JavaインタフェースSomethingMBean
とそのインタフェースを実装するJavaクラスSomething
を記述することで定義されます。インタフェースのすべてのメソッドは、MBeanの属性か操作のいずれかを定義します。デフォルトでは、すべてのメソッドは操作を定義します。属性と操作は、特定の設計パターンに従った簡単なメソッドです。標準MBeanは、開示されたすべての属性と操作のメソッドを一覧にしたMBeanインタフェースと、このインタフェースを実装し、計測されたリソースに機能を割り当てるクラスから構成されます。
以降のセクションでは、標準MBeanの例と、MBeanを管理する簡単なJMXエージェントを詳細に分析します。サンプル・コードはディレクトリwork_dir/jmx_examples/Essential/com/example/mbeans.
から抜粋しています。
HelloMBean
という非常に基本的なMBeanインタフェースの例を、コード例2-1に示します。
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メソッドです。設定メソッドを使用すると、マネージャはパラメータと同じ型の値を属性に新たに書き込むことができます。
次のセクションでは、これらの操作および属性の実装を説明します。
コード例2-1に示したHello
クラスは、HelloMBean
を実装します。
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エージェントを示しています。
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()
を呼び出し、属性値を取得および設定しています。
クラスの例題を検証したあと、今度は例題を実行します。Java Platform, Standard EditionにはJConsoleという管理およびモニタリング・コンソールが付属しており、この例ではMBeanとの対話に使用されています。JConsoleはJavaSE_HOME/bin/jconsole
にあります。JavaSE_HOMEはJava Platform, Standard Edition (Java SEプラットフォーム)がインストールされたディレクトリです。
例を実行するには、次の手順に従うか、README
ファイルを参照します。
/jmx_examples/Essential
をまだ開いていない場合は開きます。
$
cd work_dir/jmx_examples/Essential
$
javac com/example/mbeans/*.java
Main
アプリケーションを起動します。
$
java com.example.mbeans.Main
何かの発生を待機中のMain
に関する確認が表示されます。
$
jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
com.example.mbeans.Main
を選択し、「接続」をクリックします。
プラットフォームの現在のアクティビティのサマリーが表示されます。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
com.example.mbeans
ノードを展開します。
Main
で作成され、登録されたMBean Hello
の例が表示されます。Hello
をクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。
Hello
MBeanノードをクリックします。
Hello
MBeanのメタデータとそれに関連する記述子が表示されます。
Hello
MBeanのAttributes
ノードをクリックします。
Hello
クラスで定義されたMBean属性が表示されます。
CacheSize
属性の値を150に変更します
Main
を起動した端末ウィンドウで、この属性の変更を確認が表示されます。
Operations
ノードをクリックします。
ここで、Hello
MBeanで宣言された2つの操作、sayHello()
とadd()
が表示されます。
sayHello
」ボタンをクリックして、sayHello()
操作を起動します。
メソッドが正常に呼び出されたことがJConsoleのダイアログ・ボックスに通知され、Main
が起動している端末のウィンドウに「hello, world」というメッセージが表示されます。
add()
操作で加算する2つの整数を指定し、「add
」ボタンをクリックします。
「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
インタフェースを実装している点で異なっています。
前述のように、この例題とセクション「標準MBean」で示した例題の唯一の違いは、MBeanの実装により通知の送信ができるという点です。
コード例2-1に示したように、通知はNotificationBroadcaster
インタフェースを実装することで起動します。
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
は、前出の例で使用されたものと同じです。
クラスの例題を検証したあと、今度は例題を実行します。この例では、Hello
MBeanとの対話に再度JConsoleを使用します。例を実行する場合は、次の手順に従うか、README
ファイルを参照してください。
/jmx_examples/Notification
をまだ開いていない場合は開きます。
$
cd work_dir/jmx_examples/Notification
$
javac com/example/mbeans/*.java
Main
アプリケーションを起動します。
$
java com.example.mbeans.Main
何かの発生を待機中のMain
に関する確認が表示されます。
$
jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
com.example.mbeans.Main
を選択し、「接続」をクリックします。
プラットフォームの現在のアクティビティのサマリーが表示されます。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
com.example.mbeans
ノードを展開します。
Main
で作成され、登録されたMBean Hello
の例が表示されます。Hello
をクリックすると、関連するAttributes
、Operations
、およびNotifications
ノードがMBeanツリーに表示されます。
Hello
MBeanノードをクリックします。
これによって、MBeanのメタデータと関連する記述子が表示されます。
Notifications
ノードをクリックします。
空のパネルが表示されます。
現在の受領通知数(0)が、Notificationsノード・ラベルに表示されます。
Hello
MBeanのAttributes
ノードをクリックし、CacheSize
属性を150に変更します
Main
を起動した端末ウィンドウで、この属性の変更を確認が表示されます。また、Notificationsノードに表示される受領通知数が1に変更されています。
Hello
MBeanのNotifications
ノードをふたたびクリックします。
送信された通知の詳細が表示されます。
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
標準型にマップされます。
jmx_examples.zip
ファイルをダウンロードして解凍すると、MXBeanの操作を説明したサンプル・プログラムがwork_dir/jmx_examples/MXBean/com/example/mxbeans
ディレクトリに作成されます。MXBeanのサンプルには、次のファイルが含まれています。
QueueSamplerMXBean
インタフェース。QueueSampler
クラス。QueueSample
Javaの型で、MXBeanインタフェース内のgetQueueSample()
メソッドによって返されます。Main
、サンプルを設定して実行するプログラム。MXBeanのサンプルには、次のアクションが含まれています。
type Queue<String>
のリソースを管理する、単純なMXBeanを定義する。getQueueSample
を宣言し、次の値をバンドルするJavaクラスQueueSample
を返す。コード例2-1は、QueueSamplerMXBean
インタフェースのサンプル・コードを示しています。
package com.example.mxbeans; public interface QueueSamplerMXBean { public QueueSample getQueueSample(); public void clearQueue(); }
この例からわかるように、MXBeanインタフェースの宣言は標準MBeanの宣言とまったく同じです。QueueSamplerMXBean
インタフェースでは、getQueueSample
とclearQueue
という2つの操作を宣言しています。
QueueSampler
クラスは、コード例2-1に示すように、QueueSamplerMXBean
インタフェースを実装しています。
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のインスタンスを返します。
QueueSampler
によって返された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インタフェースとこれを実装するクラス、および返されるJava型を定義したら、次はMXBeanを作成してMBeanサーバーに登録する必要があります。これらのアクションは、サンプル・クラス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サーバーに登録されます。
例を実行するには、次の手順に従うか、README
ファイルを参照します。
/jmx_examples/MXBean
をまだ開いていない場合は開きます。
$
cd work_dir/jmx_examples/MXBean
$
javac com/example/mxbeans/*.java
Main
アプリケーションを起動します。
$
java com.example.mxbeans.Main
何かの発生を待機中のMain
に関する確認が表示されます。
$
jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
com.example.mxbeans.Main
を選択し、「接続」をクリックします。
プラットフォームの現在のアクティビティのサマリーが表示されます。
このパネルに、現在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が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();
コード例2-2では、newMXBeanProxyメソッドを使用してMXBeanプロキシを作成しています。newMBeanProxy
という等価のメソッドがあるのは、ほかの型のMBeanで使用するプロキシを作成するためです。newMBeanProxy
およびnewMXBeanProxy
メソッドの使用法はまったく同じです。
記述子によって、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
インタフェース。QueueSampler
クラス。QueueSample
Javaの型で、MXBeanインタフェース内のgetQueueSample()
メソッドによって返されます。Version
。MBeanインタフェースの現在のバージョンを示す注釈。この例に示すQueueSampler
MXBeanは、第2章「MXBeanの導入」に示したMXBeanの例と基本的に同じアクションを実行していますが、MBean記述子が追加されている点が異なります。この例は、DescriptorKey
メタ注釈を使用することで、標準MBean (またはMXBean)インタフェース内の注釈によって標準MBean (またはMXBean)の記述子に新しい記述子を追加する方法を示しています。
新しい注釈DescriptorKey
を使用することで、標準MBean (またはMXBean)インタフェース内の注釈によって標準MBean (またはMXBean)の記述子に情報を追加できます。これによって、ツールで既存の管理モデルから標準MBeanを生成し、そのモデルからの情報を別のファイルではなく生成されたMBeanインタフェースに含めることができます。
コード例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
記述子に追加されます。
次の例で使用されているQueueSamplerMXBean
インタフェースは、MBean記述子を実装してその情報の一部を公開する範囲にかぎり、MXBeanの例で使用されているインタフェースとはわずかに異なります。
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
のどちらかの名前に設定されます。
例を実行するには、次の手順に従うか、README
ファイルを参照します。
/jmx_examples/Descriptors
をまだ開いていない場合は開きます。
$
cd work_dir/jmx_examples/Descriptors
$
javac com/example/mxbeans/*.java
Main
アプリケーションを起動します。
$
java com.example.mxbeans.Main
何かの発生を待機中のMain
に関する確認が表示されます。
$
jconsole
JConsoleツールが開き、接続可能な稼動中のJMXエージェントのリストが表示されます。
com.example.mxbeans.Main
を選択し、「接続」をクリックします。
プラットフォームの現在のアクティビティのサマリーが表示されます。
このパネルに、現在MBeanサーバーに登録されているすべてのMBeanが表示されます。
com.example.mxbeans
ノードを展開します。
Mainで作成され、登録されたMBean QueueSampler
の例が表示されます。QueueSampler
をクリックすると、関連するAttributesおよびOperationsノードがMBeanツリーに表示されます。また、MBeanInfo
記述子表にはauthor
およびversion
フィールドも表示されます。
QueueSampler
MBeanノードの下にあるAttributes
およびOperations
ノードを展開します。
AttributesとOperationsが個別に表示されます。
QueueSample
ノードを選択します。
MBeanAttributeInfo
記述子表にdisplayName
フィールドが表示されます。
clearQueue
ノードを選択します。
MBeanOperationInfo
記述子表にdisplayName
フィールドが表示されます。