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

第 2 章

JMX API の基本要素

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

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

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

2.1 標準 MBean

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

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

2.1.1 MBean インタフェース

きわめて基本的な MBean インタフェース HelloMBean の例を、コード 例 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 クラスについては、「2.1.2 MBean の実装」で説明します。

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

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

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

2.1.2 MBean の実装

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

コード 例 2-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; 
} 
 

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

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

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

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

2.1.3 リソースの管理

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

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

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

コード 例 2-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); 
   } 
} 
 

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 オブジェクトは、これ自体が「2.1.2 MBean の実装」で定義されたMBean Hello のインスタンスです。

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

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

2.1.4 標準 MBean の例題の実行

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

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

  1. work_dir/jmx_examples/Essentials をまだ開いていない場合は、開きます。
  2. $ cd work_dir/jmx_examples/Essentials

  3. Java クラスの例をコンパイルします。
  4. $ javac com/example/mbeans/*.java

  5. Main アプリケーションを起動し、同じホストでのローカル監視を許可します。
  6. $ java -Dcom.sun.management.jmxremote com.example.mbeans.Main

    イベントの発生を待機中の Main に関する確認が表示されます。

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

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

  9. [JConsole: エージェントに接続] のリストから com.example.mbeans.Main を選択し、[接続] をクリックします。
  10. プラットフォームの現在のアクティビティの概要が表示されます。

  11. [MBeans] タブをクリックします。
  12. このパネルに、現在 MBean サーバに登録されているすべての MBean が表示されます。

  13. 左側のフレームで、com.example.mbeans のドロップダウンアイコンをクリックします。
  14. Main で作成され、登録された MBean Hello の例が表示されます。

  15. Hello MBean をクリックします。
  16. Hello クラスで定義された MBean 属性が表示されます。

  17. CacheSize 属性の値を 150 に変更します。
  18. Main を起動した端末ウィンドウに、この属性の変更を確認するプロンプトが表示されます。

  19. [操作] タブをクリックします。
  20. ここで、Hello MBean で宣言された 2 つの操作、sayHello()add() が表示されます。

  21. [sayHello] ボタンをクリックして、sayHello() 操作を起動します。
  22. [JConsole] ダイアログボックスにより、メソッドが正常に起動したことが通知され、Main が稼動する端末ウィンドウにメッセージ “hello, world” が表示されます。

  23. add() 操作で加算する 2 つの整数を指定し、[add] ボタンをクリックします。
  24. [JConsole] ダイアログボックスに解答が通知されます。

  25. [情報] タブをクリックします。
  26. Hello MBean のオブジェクト名とその実装クラスが表示されます。

  27. [接続] をクリックし、次に [終了] をクリックして JConsole を終了します。

2.2 通知の送信

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

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

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

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

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

2.2.1 NotificationBroadcaster インタフェース

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

通知は NotificationBroadcaster インタフェースを実装すると起動します。これはコード 例 2-4 で説明しています。

コード 例 2-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; 
} 
 

コード 例 2-4 からわかるように、この Hello MBean の実装により NotificationBroadcasterSupport クラスが拡張され、このクラスの拡張により NotificationEmitter インタフェースが拡張されます。

操作と属性は他の場合と同様に設定されますが、cacheSize 属性の設定メソッドは、今度は新しい値 oldSize を定義します。この値は設定操作の前に cacheSize 属性の値を記録します。

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

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

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

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

2.2.2 MBean の通知の例題の実行

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

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

  3. Java クラスの例をコンパイルします。
  4. $ javac com/example/mbeans/*.java

  5. Main アプリケーションを起動し、同じホストでのローカル監視を許可します。
  6. $ java -Dcom.sun.management.jmxremote com.example.mbeans.Main

    イベントの発生を待機中の Main に関する確認が表示されます。

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

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

  9. [JConsole: エージェントに接続] のリストから com.example.mbeans.Main を選択し、[接続] をクリックします。
  10. プラットフォームの現在のアクティビティの概要が表示されます。

  11. [MBeans] タブをクリックします。
  12. このパネルに、現在 MBean サーバに登録されているすべての MBean が表示されます。

  13. 左側のフレームで、com.example.mbeans のドロップダウンアイコンをクリックします。
  14. Main で作成され、登録された MBean Hello の例が表示されます。

  15. Hello MBean をクリックします。
  16. Hello クラスで定義された MBean 属性が表示されます。

  17. [通知] タブをクリックします。
  18. 空のパネルが表示されます。

  19. [登録] ボタンをクリックします。
  20. 現在の受領通知数 (0) が、[通知] タブのヘッダに表示されます。

  21. [属性] タブをクリックし、CacheSize 属性の値を 150 に変更します。
  22. Main を起動した端末ウィンドウに、この属性の変更を確認するプロンプトが表示されます。また、[通知] タブに表示される受領通知数が 1 に変更されています。

  23. [通知] タブを再度クリックします。
  24. 送信された通知の詳細が表示されます。

  25. [接続] をクリックし、次に [終了] をクリックして JConsole を終了します。

 


目次 | 前の項目 | 次の項目 Java Management Extensions (JMX) テクノロジのチュートリアル
Java Management Extensions (JMX), Java 2 Platform Standard Edition 5.0