模型MBean是一种通用的、可配置的MBean,任何人可以用它来快速转化任何资源。模型MBean是一种动态MBean,实现了指定的接口。这些接口定义的结构,在实现这些接口时,提供了一个实例化MBean的默认的和可配置的行为。
关于模型MBean的理解不是本文重点,下面是一个参考,当然最好的方式是看JMX规范:
http://www.51testing.com/?uid-43487-action-viewspace-itemid-98380
环境:JMX1.2 JDK1.6
1. Hello.java
package com.jmxdemo.model; public class Hello { private String name; public Hello() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void print() { System.out.println("Hello " + name + "!"); } }
Hello是被管理对象,不要求实现以MBean结尾的接口,MBeanServer通过RequiredModelMBean来对其进行管理,在HelloModel.java中我们可以看到Hello和RequiredModelMBean是通过何种方式关联的。
2. HelloModel.java
package com.jmxdemo.model; import java.lang.reflect.Constructor; import javax.management.Descriptor; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.RuntimeOperationsException; import javax.management.modelmbean.DescriptorSupport; import javax.management.modelmbean.InvalidTargetObjectTypeException; import javax.management.modelmbean.ModelMBeanAttributeInfo; import javax.management.modelmbean.ModelMBeanConstructorInfo; import javax.management.modelmbean.ModelMBeanInfo; import javax.management.modelmbean.ModelMBeanInfoSupport; import javax.management.modelmbean.ModelMBeanOperationInfo; import javax.management.modelmbean.RequiredModelMBean; public class HelloModel { public static RequiredModelMBean createModelBean() throws RuntimeOperationsException, MBeanException, InstanceNotFoundException, InvalidTargetObjectTypeException { // 模型MBean信息 ModelMBeanInfo info = buildModelMBeanInfo(); // 模型MBean RequiredModelMBean modelMBean = new RequiredModelMBean(info); modelMBean.setManagedResource(new Hello(), "ObjectReference"); return modelMBean; } protected static ModelMBeanInfo buildModelMBeanInfo() { // -- // attributes // ------------------------------------------------------------------ ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[1]; // name attribute Descriptor nameDesc = new DescriptorSupport(); nameDesc.setField("name", "name"); nameDesc.setField("displayName", "myname"); nameDesc.setField("setMethod", "setName"); nameDesc.setField("getMethod", "getName"); nameDesc.setField("descriptorType", "attribute"); attributes[0] = new ModelMBeanAttributeInfo("name", "java.lang.String", "name say hello to", true, true, false, nameDesc); // -- // operations // ------------------------------------------------------------------- ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[3]; String className = Hello.class.getName(); // setName method MBeanParameterInfo[] setNameParams = new MBeanParameterInfo[] { new MBeanParameterInfo( "name", "java.lang.String", "name say hello to") }; Descriptor setNameDesc = new DescriptorSupport(new String[] { "name=setName", "descriptorType=operation", "class=" + className, "role=operation" }); operations[0] = new ModelMBeanOperationInfo("setName", "set name", setNameParams, "void", MBeanOperationInfo.ACTION, setNameDesc); // getName method Descriptor getNameDesc = new DescriptorSupport(new String[] { "name=getName", "descriptorType=operation", "class=" + className, "role=operation" }); operations[1] = new ModelMBeanOperationInfo("getName", "get name", null, "java.lang.String", MBeanOperationInfo.ACTION, getNameDesc); // print method Descriptor printDesc = new DescriptorSupport(new String[] { "name=print", "descriptorType=operation", "class=" + className, "role=operation" }); operations[2] = new ModelMBeanOperationInfo("print", "print name", null, "void", MBeanOperationInfo.ACTION, printDesc); // -- // constructors // ---------------------------------------------------------------------- ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[1]; Constructor<?>[] ctors = Hello.class.getConstructors(); // default constructors // Descriptor helloDesc = new DescriptorSupport(); // helloDesc.setField("name", "Hello"); // helloDesc.setField("descriptorType", "operation"); // helloDesc.setField("role", "constructor"); // helloDesc.setField("displayName", "Hello"); // constructors[0] = new ModelMBeanConstructorInfo( // "Hello(): Constructs a Hello Object", ctors[0], helloDesc); constructors[0] = new ModelMBeanConstructorInfo("default constructor", ctors[0], null); // ModelMBeanInfo ModelMBeanInfo mmbeanInfo = new ModelMBeanInfoSupport(className, "Simple implementation of model bean.", attributes, null, operations, null, null); return mmbeanInfo; } }
将Hello管理对象和RequiredModelMBean进行管理,提供给MBeanServer
ModelAgent.java
package com.jmxdemo.model; import java.io.IOException; import java.rmi.registry.LocateRegistry; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.RuntimeOperationsException; import javax.management.modelmbean.InvalidTargetObjectTypeException; import javax.management.modelmbean.RequiredModelMBean; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import com.sun.jdmk.comm.HtmlAdaptorServer; public class ModelAgent { public static final String DOMAIN = "MyModelMBean"; public static void main(String[] args) throws RuntimeOperationsException, InstanceNotFoundException, MBeanException, InvalidTargetObjectTypeException, MalformedObjectNameException, NullPointerException, InstanceAlreadyExistsException, NotCompliantMBeanException, IOException { // mbean server MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN); // register hello model mbean RequiredModelMBean hello = HelloModel.createModelBean(); ObjectName helloname = new ObjectName(DOMAIN + ":name=helloModel"); server.registerMBean(hello, helloname); // manage MBeans via web HtmlAdaptorServer htmlAdaptor = new HtmlAdaptorServer(); htmlAdaptor.setPort(9998); ObjectName htmlname = new ObjectName(DOMAIN + ":name=htmlAdaptor"); server.registerMBean(htmlAdaptor, htmlname); htmlAdaptor.start(); System.out.println("html adaptor start..."); // manage MBeans via RMI LocateRegistry.createRegistry(9999); JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/mserver"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server); cs.start(); System.out.println("RMI start..."); } }
通过Http和RMI两种方式提供远程访问功能。
测试:
1. 打开浏览器输入http://localhost:9998/进行管理
2.在jconsole远程连接中输入RMI访问地址,
即service:jmx:rmi:///jndi/rmi://localhost:9999/mserver,进入管理界面进行管理。
ps:打开jconsole方式
如果配置了JAVA_HOME,则打开命令行,输入jconsole即可;
在JDK安装目录下的bin目录中找到jconsole.exe,打开即可
问题:
在HelloModel.java中如果把constructors[0] = new ModelMBeanConstructorInfo("default constructor", ctors[0], null);换成注释部分,程序会报下面错误,找不到解决办法。
Exception in thread "main" javax.management.RuntimeOperationsException: Exception occurred in ModelMBeanConstructorInfo constructor at javax.management.modelmbean.ModelMBeanConstructorInfo.<init>(Unknown Source) at com.jmxdemo.model.HelloModel.buildModelMBeanInfo(HelloModel.java:91) at com.jmxdemo.model.HelloModel.createModelBean(HelloModel.java:25) at com.jmxdemo.model.ModelAgent.main(ModelAgent.java:34) Caused by: java.lang.IllegalArgumentException: Invalid descriptor passed in parameter ... 4 more
如解决,请告知,3Q!!!