| 目次 | 前の項目 | 次の項目 | 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.