| 目次|前|次 | 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つずつインクリメントするcacheSizeoldSizethis.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フィールドが表示されます。