目次 | 前の項目 | 次の項目 | Java Management Extensions (JMX) テクノロジのチュートリアル |
この章では、標準および動的な管理 Beans (MBeans) の概念を紹介します。また、Java Management Extensions (JMX) テクノロジを使用して MBeans 上でローカルおよびリモートから操作を実行する方法について示します。
この例では、標準および動的 MBeans のみを説明します。
第 2 章 、「JMX API の基本要素」で説明したように、標準 MBean は内部のメソッドの名前を使用して、管理インタフェースを静的に定義する管理 Bean です。動的 MBean は、特定の Java インタフェースを実装し、実行時に自らの属性と操作を示します。
JMX テクノロジは、RMI に基づいてコネクタを定義します。RMI コネクタは、Java Remote Method Protocol (JRMP) と Internet Inter-Object Request Broker (ORB) Protocol (IIOP) の 2 つの標準 RMI トランスポートをサポートしています。このコネクタを使用すると、MBean サーバの MBean にリモート接続し、ローカルで操作を実行するのとまったく同じように、その MBean で操作を実行できます。
この例は、標準 MBean と動的 MBean の実装を説明することを目的としています。また、両 MBean 上でローカルに、またサーバとリモートクライアント間の RMI 接続を通じてリモートに操作を実行する方法も示します。
この例を実行する場合
SimpleStandard
と SimpleDynamic
の MBean を登録SimpleStandard
と SimpleDynamic
の MBean を登録
RMI コネクタの例は、ディレクトリ work_dir/jmx_examples/Basic
内にあります。
次のセクションでは、基本的な MBean の例題で使用される各クラスを分析し、各クラスがこれまでのセクションで説明した操作をどのように実行するかについて説明します。
Server.java
クラスは、その大きさにより、いくつかのコード (抜粋) で現れます。
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); waitForEnterPressed(); String domain = mbs.getDefaultDomain(); waitForEnterPressed(); String mbeanClassName = "SimpleStandard"; String mbeanObjectNameStr = domain + ":type=" + mbeanClassName + ",index=1"; ObjectName mbeanObjectName = createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr); waitForEnterPressed(); printMBeanInfo(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); mbeanClassName = "SimpleDynamic"; mbeanObjectNameStr = domain + ":type=" + mbeanClassName + ",index=1"; mbeanObjectName = createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr); waitForEnterPressed(); printMBeanInfo(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); [...]
このクラスを検討すると、次のイベントが起こっていることがわかります。
まず、Server.java
クラスは、MBeanServerFactory
クラスの createMBeanServer()
メソッドを呼び出して mbs
と呼ばれる新しい MBean サーバを作成します。
次に MBean サーバを登録するデフォルトドメインを、MBeanServer
インタフェースの getDefaultDomain()
メソッドを呼び出して取得します。このドメインは、文字列 domain
で識別されます。
MBean クラス SimpleStandard
も、この場合は文字列 mbeanClassName
という変数により識別されます。SimpleStandard
は、この MBean をインスタンスとする Java オブジェクトの Java クラスの名前です。SimpleStandard.java
オブジェクトについては、「3.1.1.3 SimpleStandard.java」を参照してください。
もう一つの変数、文字列 mbeanObjectNameStr
は、ドメインと次のキー=値ペアを組み合わせて定義されます。
type
。この場合は、mbeanClassName
。index
。この MBean を、後で作成される同じタイプの他の MBeans と区別します。この場合、インデックス番号は 1
です。
mbeanObjectNameStr
の目的は、人間が読むことができる識別子を MBean に割り当てることです。
createSimpleMBean() の呼び出しにより、指定されたオブジェクト名の SimpleStandard MBean がローカル MBean サーバで作成され、登録されます。
次に、printMBeanInfo()
と manageSimpleMBean()
の両方の操作が、SimpleStandard
MBean で実行されます。createSimpleMBean()
と同様に、これらのメソッドは後で Server.java
コードで定義されており、コード 例 3-3 と XXX に例を示しています。
このコードには記述されていませんが、SimpleDynamic
型の 2 番目の MBean が、SimpleStandard
MBean とまったく同じ方法で MBean サーバに作成され、登録されます。その名前が示すように、この MBean は「3.1.1.4 SimpleDynamic.java」 で説明する SimpleDynamic
Java オブジェクトのインスタンスです。
[...] JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); cs.start(); waitForEnterPressed(); cs.stop(); [...]
コード 例 3-2 では、RMI コネクタサーバは、MBeans で操作をリモートから実行できるように作成されています。クラス JMXServiceURL
への呼び出しにより、コネクタサーバのアドレスとして機能する url
と呼ばれる新しいサービス URL が作成されます。この例では、サービス URL は「エンコード形式」ではなく「JNDI 形式」で指定されます (JNDI 形式の詳細は、javax.management.remote.rmi
パッケージの API ドキュメントを参照)。このサービス URL は、次の内容を定義しています。
rmi
で表されるデフォルトの RMI トランスポートを使用する 9999
で稼動し、サーバアドレスは server
の名前で登録される。例で指定されるポート 9999
は任意の数字。使用可能なポートを指定できる
RMI コネクタサーバ cs
は、パラメータにサービス URL url
、null
環境マップ、および MBean サーバ mbs
を使用して、コンストラクタ JMXConnectorServerFactory
を呼び出して作成されます。コネクタサーバ cs
は、JMXConnectorServer
の start()
メソッドを呼び出し、RMIConnectorServer
が RMI オブジェクト server
を RMI レジストリにエクスポートすることで起動されます。この接続は、Enter キーを押すまで有効です。これは Server
コードの後半で定義する簡単なメソッド waitForEnterPressed
の手順に従ったものです。
[...] private static ObjectName createSimpleMBean(MBeanServer mbs, String mbeanClassName, String mbeanObjectNameStr) { echo("\n>>> Create the " + mbeanClassName + " MBean within the MBeanServer"); echo( "ObjectName = " + mbeanObjectNameStr); try { ObjectName mbeanObjectName = ObjectName.getInstance(mbeanObjectNameStr); mbs.createMBean(mbeanClassName, mbeanObjectName); return mbeanObjectName; } catch (Exception e) { echo( "!!! Could not create the " + mbeanClassName + " MBean !!!"); e.printStackTrace(); echo("\nEXITING...\n"); System.exit(1); } return null; } [...]
コード 例 3-3 は、createSimpleStandard()
メソッドの定義を示しています。このメソッドでは、オブジェクト名 mbeanObjectNameStr
を使用した MBean インスタンスが、ObjectName
インタフェースの getInstance()
メソッドに渡され、MBean サーバ内で MBean に登録するための新しいオブジェクト名が作成されます。最終的なオブジェクト名インスタンスは、mbeanObjectName
に設定されます。次に MBeanServer
のメソッド createMBean()
により、mbeanClassName
で識別される Java オブジェクトと MBean インスタンス mbeanObjectName
の組み合わせにより MBean のインスタンスが作成され、MBean サーバ mbs
にこの MBean が登録されます。
[...] private static void printMBeanInfo(MBeanServer mbs, ObjectName mbeanObjectName, String mbeanClassName) { MBeanInfo info = null; try { info = mbs.getMBeanInfo(mbeanObjectName); } catch (Exception e) { echo( "!!! Could not get MBeanInfo object for " + mbeanClassName +" !!!"); e.printStackTrace(); return; } MBeanAttributeInfo[] attrInfo = info.getAttributes(); if (attrInfo.length > 0) { for (int i = 0; i < attrInfo.length; i++) { echo(" ** NAME: " + attrInfo[i].getName()); echo(" DESCR: " + attrInfo[i].getDescription()); echo(" TYPE: " + attrInfo[i].getType() + "READ:"+ attrInfo[i].isReadable() + "WRITE:"+ attrInfo[i].isWritable()); } } else echo(" ** No attributes **"); [...]
コード 例 3-4 は、printMBeanInfo()
メソッドの定義を示しています。printMBeanInfo()
メソッドは MBeanServer
のメソッド getMBeanInfo()
を呼び出して、mbeanObjectName
により開示される属性と操作の詳細を取得します。MBeanAttributeInfo
は次のメソッドを定義します。各メソッドは mbeanObjectName
MBean の属性に関する情報を取得する場合に順に呼び出されます。
getName
。属性の名前を取得するgetDescription
。人間が読むことのできる属性の説明を取得するgetType
。属性のクラス名を取得するisReadable
。属性が読み出し可能か否かを判断するisWritable
。属性が書き込み可能か否かを判断する
ここに示していませんが、mbeanObjectName
MBean のコンストラクタ、操作、通知に関する情報を取得するために呼び出しが行われます。
MBeanConstructorInfo
。MBean の Java クラスに関する情報を取得するMBeanOperationInfo
。MBean で実行される操作の内容、MBean で使われるパラメータの種類を学習するMBeanNotificationInfo
。MBean の操作が実行された場合に、MBean から送信される通知の種類を調べる[...] private static void manageSimpleMBean(MBeanServer mbs, ObjectName mbeanObjectName, String mbeanClassName) { try { printSimpleAttributes(mbs, mbeanObjectName); Attribute stateAttribute = new Attribute("State", "new state"); mbs.setAttribute(mbeanObjectName, stateAttribute); printSimpleAttributes(mbs, mbeanObjectName); echo("\n Invoking reset operation..."); mbs.invoke(mbeanObjectName, "reset", null, null); printSimpleAttributes(mbs, mbeanObjectName); } catch (Exception e) { e.printStackTrace(); } } private static void printSimpleAttributes( MBeanServer mbs, ObjectName mbeanObjectName) { try { String State = (String) mbs.getAttribute(mbeanObjectName, "State"); Integer NbChanges = (Integer) mbs.getAttribute(mbeanObjectName, "NbChanges"); } catch (Exception e) { echo( "!!! Could not read attributes !!!"); e.printStackTrace(); } } [...]
コード 例 3-5 は簡単な MBean を管理するための方法を示しています。
まず、manageSimpleMBean()
メソッドが、Server
でも定義される printSimpleAttributes()
メソッドを呼び出します。printSimpleAttributes()
メソッドは、MBean mbeanObjectName
から state
と呼ばれる MBean 属性と、NbChanges
と呼ばれるもう一つの MBean 属性を取得します。これらの属性はいずれも、「3.1.1.3 SimpleStandard.java」に示すように、SimpleStandard
クラスで定義されます。
次に manageSimpleMBean()
メソッドは、Attribute
クラスのインスタンスである属性 stateAttribute
を定義します。stateAttribute
属性は、値 new state
を SimpleStandard
で定義される既存の属性 state
に関連付けます。次に MBeanServer
メソッド setAttribute()
の呼び出しにより、mbeanObjectName
MBean の状態が stateAttribute
で定義される新しい状態に設定されます。
最後に MBeanServer
メソッド invoke()
の呼び出しにより、mbeanObjectName
MBean の reset
操作が起動します。reset
操作は、SimpleStandard
クラスで定義されます。
SimpleStandardMBean.java
クラスをコード 例 3-6 に示します。
public interface SimpleStandardMBean { public String getState(); public void setState(String s); public int getNbChanges(); public void reset(); }
SimpleStandardMBean.java
クラスは、MBean SimpleStandard
の簡単な JMX 仕様の管理インタフェースです。このインタフェースは、JMX エージェントからの管理のために SimpleStandard
で定義された 4 つの操作を公開します。
SimpleStandard.java
クラスをコード 例 3-7 に示します。
public class SimpleStandard extends NotificationBroadcasterSupport implements SimpleStandardMBean { public String getState() { return state; } public void setState(String s) { state = s; nbChanges++; } public int getNbChanges() { return nbChanges; } public void reset() { AttributeChangeNotification acn = new AttributeChangeNotification(this, 0, 0, "NbChanges reset", "NbChanges", "Integer", new Integer(nbChanges), new Integer(0)); state = "initial state"; nbChanges = 0; nbResets++; sendNotification(acn); } public int getNbResets() { return nbResets; } public MBeanNotificationInfo[] getNotificationInfo() { return new MBeanNotificationInfo[] { new MBeanNotificationInfo( new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }, AttributeChangeNotification.class.getName(), "This notification is emitted when the reset() method is called.") }; } private String state = "initial state"; private int nbChanges = 0; private int nbResets = 0; }
SimpleStandard
クラスは、簡単な JMX 仕様の標準 MBean を定義します。
SimpleStandard
MBean は、「3.1.1.2 SimpleStandardMBean.java」に示すように、対応する SimpleStandardMBean
インタフェースを実装することで、操作と属性を管理用に開示します。
この MBean で開示される簡単な操作を次に示します。
リセット操作により発行される通知は、クラス AttributeChangeNotification
のインスタンスであり、リセットの呼び出し前に State
属性で実行された変更数に関する情報を収集します。送信される通知の内容は、MBeanNotificationInfo
インスタンスで定義されます。
SimpleDynamic
クラスをコード 例 3-8 に示します。
public class SimpleDynamic extends NotificationBroadcasterSupport implements DynamicMBean { public SimpleDynamic() { buildDynamicMBeanInfo(); } [...]
SimpleDynamic
の動的 MBean では、DynamicMBean
インタフェースを実装することで、実行時に管理用の属性と操作を開示する方法を示します。ここでは、まず、MBean に関する情報を動的に取得するためのメソッド buildDynamicMBeanInfo()
の定義から開始します。buildDynamicMBeanInfo()
メソッドは、動的 MBean に MBeanInfo
を構築します。
SimpleDynamic
の他のコードは、DynamicMBean
インタフェースの実装に対応しています。開示される属性、操作、通知は、SimpleStandard
MBean で開示されるものと同じです。
ClientListener.java
クラスをコード 例 3-9 に示します。
public class ClientListener implements NotificationListener { public void handleNotification(Notification notification, Object handback) { System.out.println("\nReceived notification:" + notification); } }
ClientListener
クラスは、簡単な JMX 仕様の通知リスナを実装します。
通知が受領されると、NotificationListener
インタフェースの handleNotification()
メソッドが呼び出され、通知の受領を確認するためのメッセージが印刷されます。
Client.java
クラスをコード 例 3-10 に示します。
public class Client { public static void main(String[] args) { try { // Create an RMI connector client // JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); ClientListener listener = new ClientListener(); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); waitForEnterPressed(); // Get domains from MBeanServer // String domains[] = mbsc.getDomains(); for (int i = 0; i < domains.length; i++) { System.out.println("Domain[" + i + "] = " + domains[i]); } waitForEnterPressed(); String domain = mbsc.getDefaultDomain(); // Create SimpleStandard MBean // ObjectName mbeanName = new ObjectName(domain +":type=SimpleStandard,index=2"); mbsc.createMBean("SimpleStandard", stdMBeanName, null, null); waitForEnterPressed(); // Create SimpleDynamic MBean // ObjectName dynMBeanName = new ObjectName(domain +":type=SimpleDynamic,index=2"); echo("\nCreate SimpleDynamic MBean..."); mbsc.createMBean("SimpleDynamic", dynMBeanName, null, null); waitForEnterPressed(); // Get MBean count // echo("\nMBean count = " + mbsc.getMBeanCount()); // Query MBean names // echo("\nQuery MBeanServer MBeans:"); Set names = mbsc.queryNames(null, null); for (Iterator i = names.iterator(); i.hasNext(); ) { echo( "ObjectName = " + (ObjectName) i.next()); } waitForEnterPressed(); mbsc.setAttribute(stdMBeanName, new Attribute("State", "changed state")); SimpleStandardMBean proxy = (SimpleStandardMBean) MBeanServerInvocationHandler.newProxyInstance( mbsc, stdMBeanName, SimpleStandardMBean.class, false); echo("\nState = " + proxy.getState()); ClientListener listener = new ClientListener(); mbsc.addNotificationListener(stdMBeanName, listener, null, null); mbsc.invoke(stdMBeanName, "reset", null, null); mbsc.removeNotificationListener(stdMBeanName, listener); mbsc.unregisterMBean(stdMBeanName); [...] jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } } [...]
Client.java
クラスは、RMI コネクタクライアントを作成します。このクライアントは、Server.java
で作成される RMI コネクタサーバへの接続用に設定されます。
Client.java
は Server.java
で定義されるのと同じサービス URL、url
を定義します。これによって、コネクタクライアントは、ローカルホストのポート 9999
で動作する RMI レジストリから RMI コネクタサーバスタブ server
を取得し、RMI コネクタサーバに接続することができます。
RMI レジストリがこのように特定された後、コネクタクライアントを作成できます。コネクタクライアント jmxc
は、JMXConnectorFactory
の connect()
メソッドにより作成されたインタフェース JMXConnector
のインスタンスです。connect()
メソッドは、呼び出されると、パラメータ url
と null
環境マップが渡されます。
またクライアントは、「3.1.1.5 ClientListener.java」に示すように、通知を待機する ClientListener
のインスタンスを作成します。
次に、JMXConnector
インスタンス jmxc
の getMBeanServerConnection()
メソッドを呼び出して、JMX 仕様 MBeanServerConnection
のインスタンス mbsc
が作成されます。
コネクタクライアントは、次に Server.java
で作成された MBean サーバに接続されると、MBeans を登録し、接続が両端から完全に透過的な状態で MBeans 上で操作を実行することができます。
クライアントは、MBeanServerConnection
の createMBean()
メソッドを呼び出して、MBean サーバに SimpleStandard
MBean と SimpleDynamic MBean を作成および登録します。そして、SimpleStandard
と SimpleDynamic
で定義された操作を、ローカル JMX 仕様の MBean 操作とまったく同様に実行します。SimpleDynamic
で実行される各操作は、SimpleStandard
で実行されるものと同じであるため、ここでは操作のコードを記載していません。
最後に、クライアントは SimpleStandard
MBean の登録を解除し、接続を終了します。最後の removeNotificationListener
は省略可能です。これはリモートクライアントで登録されたリスナは、そのクライアントの終了時に削除されるためです。
クラスの例題を検証した後、今度は例題を実行します。例題を実行するには、次の手順に従うか、README
ファイルを参照します。
$
javac *.java
9999
で RMI レジストリを起動します。
RMI レジストリは、Server
によって RMI コネクタスタブの登録に使用されます。
$
rmiregistry 9999 &
Server
クラスを起動します。
$
java -classpath . Server
MBean サーバの作成、および MBean サーバでの SimpleStandard
MBean の作成の確認が表示されます。次に SimpleStandard
MBean に関する情報を取得し、この MBean で操作を実行する場合は、Enter キーを押すように要求されます。
SimpleStandard
での操作が終了すると、SimpleDynamic
MBean について、同じプロセスが繰り返されます。
標準および動的 MBean が作成され、各 MBean 上での操作が実行された後、RMI コネクタサーバの作成が表示されます。このサーバを使用すると、リモート Client
から MBeans 上で操作を実行できます。
Client
クラスを起動します。
$
java -classpath . Client
RMI コネクタの作成、およびコネクタサーバとの接続の作成の確認が表示されます。また、ドメイン名と、SimpleStandard
および SimpleDynamic の MBean の作成および登録が通知されます。クライアントは次に、SimpleStandard
と SimpleDynamic の両 MBean で操作を実行し、その後、両 MBean の登録を解除します。
目次 | 前の項目 | 次の項目 |
Java Management Extensions (JMX) テクノロジのチュートリアル Java Management Extensions (JMX), Java 2 Platform Standard Edition 5.0 |
Copyright © 2004 Sun Microsystems, Inc. All rights reserved.