「Java」MXBeanのサンプル

MXBeanのサンプルを書いてみたのでメモを残しておきます。
参考にしたのは以下のオラクルのページ(というかページに記載のサンプルほぼそのままです・・・)

・MXBeans
https://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html


まず、MXBean のインタフェースを作成します。今回は Person というオブジェクトを返す getPerson メソッドのみを持つインタフェースとしました。

・PersonMXBean.java

package com.example.mbean;

public interface PersonMXBean {
	public Person getPerson();
}


上記で作成したインタフェースの実装クラスを作成します。

・PersonSampler.java

package com.example.mbean;

public class PersonSampler implements PersonMXBean {

	private Person person;
	
	public PersonSampler(Person p) {
		this.person = p;
	}
	
	@Override
	public Person getPerson() {
		return person;
	}

}


以下が Person クラス。Name、Age、Email というプロパティを持たせています。
上記のチュートリアルにちょろっと書いてますが、MXBean フレームワークは Person を CompositeData に変換する際にすべての Getter を呼び出すらしいです。また、その逆に CompositeData から Person を再構築するのに ConstructorProperties アノテーションを使うのだとか。(すみません、詳しいことはわかってません・・・)

・Person.java

package com.example.mbean;

import java.beans.ConstructorProperties;

public class Person {

	private String name;
	private int age;
	private String email;
	
	@ConstructorProperties({"name", "age", "email"})
	public Person(String name, int age, String email) {
		this.name = name;
		this.age = age;
		this.email = email;
	}
	
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String getEmail() {
		return email;
	}
}


以下は、MBean Server に MXBean を登録するクラス。以下を実行すると jconsole から今回作成した MXBean が見えるはずです。

・Main.java

package com.example.mbean;

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 mxbeanName = new ObjectName("com.example:type=Person");
        
        Person person = new Person("hoge", 29, "hoge@example.com");
        PersonSampler mxbean = new PersonSampler(person);
        
        mbs.registerMBean(mxbean, mxbeanName);
                 
        System.out.println("Waiting..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 
} 


せっかくなので、クライアントコードのサンプルも残しておきます。
ポイントは「クライアントコードが Person クラスに依存していない」というところかと思います。

※ JMXClient で MBean Server に接続する際は、Main.java に「-Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false」をつけて起動してやってください。

・JMXClient.java

package com.example.mbean;

import java.io.IOException;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JMXClient {
	public static void main(String[] args) {
		JMXConnector jmxc = null;
		try {
			jmxc = JMXConnectorFactory.connect(new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi"));
			MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
			ObjectName objectName = new ObjectName("com.example:type=Person");
			CompositeDataSupport data = (CompositeDataSupport) mbsc.getAttribute(objectName, "Person");

			System.out.println("##### date#toString() #####");
			System.out.println(data);
			System.out.println();
			
			System.out.println("##### date#values() #####");
			System.out.println(data.values());
			System.out.println();
			
			System.out.println("##### date#getCompositeType() #####");
			System.out.println(data.getCompositeType().getTypeName());
			System.out.println();
			
			System.out.println("##### date#get(key) #####");
			System.out.println(data.get("name"));
			System.out.println(data.get("age"));
			System.out.println(data.get("email"));

		} catch (IOException | MalformedObjectNameException | ReflectionException | InstanceNotFoundException
				| AttributeNotFoundException | MBeanException e) {
			e.printStackTrace();
		} finally {
			try {
				jmxc.close();
			} catch (IOException e) {
			}
		}
	}
}

・実行結果

##### date#toString() #####
javax.management.openmbean.CompositeDataSupport(compositeType=javax.management.openmbean.CompositeType(name=com.example.mbean.Person,items=((itemName=age,itemType=javax.management.openmbean.SimpleType(name=java.lang.Integer)),(itemName=email,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=name,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)))),contents={age=29, email=hoge@example.com, name=hoge})

##### date#values() #####
[29, hoge@example.com, hoge]

##### date#getCompositeType() #####
com.example.mbean.Person

##### date#get(key) #####
hoge
29
hoge@example.com


ちゃんと読んでませんが、MXBean については以下あたりに詳しく書かれていそうです。

・MXBean (Java Platform SE 8)
https://docs.oracle.com/javase/jp/8/docs/api/javax/management/MXBean.html


以上になります。

[環境情報]
Windows 10
Java SE 8 Update 92