`
minghaitang
  • 浏览: 129071 次
社区版块
存档分类
最新评论

JMX MBeans之二Dynamic MBean

jmx 
阅读更多

JMX MBeans之二Dynamic MBean

必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义.
对于standard MBeans, jmx agent为之创建了metadata;而对于dynamic mbean,开发者必须自己提供被管理资源的metadata.虽然增加了难度,但是获得了灵活性。
DynamicMBean接口的定义:
  getMBeanInfo(): MBeanInfo
  getAttribute( attribute:String ): Object
  getAttributes( attributes:String[] ): AttributeList
  setAttribute( attribute:Attribute ): void
  setAttributes( attributes:AttributeList ): AttributeList
  invoke( actionName:String, params:Object[],signature:String[] ): Object
 
从概念上来说, dynamic MBean也有属性和方法,但是他们并不是通过方法直接暴露出来.
相反,在运行状态时,通过getMBeanInfo()方法,可以得到MBeanInfo对象.
这个对象包含了属性名称和类型列表, 以及方法和参数的列表,还有其他一些管理信息等metadata.
 
getAttribute
传入参数为一个属性名称,返回为对应的值对象

getAttributes
传入参数为属性名称列表,返回为对应的Attribute对象列表

setAttribute and setAttributes
传入参数为name-value pairs,把这些值写到对应的属性中.
setAttribute没有返回参数, setAttributes返回AttributeList

invoke方法
让管理程序调用任何dynamic MBean暴露出来的方法.
必须提供调用的方法名称和要传入的参数以及它们的类型.
 
行为:
当在JMX agent里注册时候, dynamic MBean和standard MBean是同样被对待的。
管理程序首先通过getMBeanInfo函数获得管理接口,得到属性和方法的名称.然后程序可以调用getters,setters和invoke方法.
在standard MBean中,MBean server使用自省发现调用的接口。而在动态MBean中,MBean server将自我描述的功能让给了getMBeanInfo()函数。开发者在此函数中,定义MBean的信息,MBean server并不会测试和验证这些信息。所以,开发者必须要保证它们的正确性。
有个问题,因为接口方法都是通过getMBeanInfo函数获得的,所以是动态的,连续的调用函数返回的数据可能不相同。这就会带来一些一致性的问题。
做个example:
 
import java.lang.reflect.Constructor;
import java.util.Iterator;
import javax.management.*;
public class SimpleDynamic implements DynamicMBean {
 /*
  *私有变量
  */
 private String state = "initial state";
 private int nbChanges = 0;
 private int nbResets = 0;
 private String dClassName = this.getClass().getName();
 private String dDescription = "Simple implementation of a dynamic MBean.";
 private MBeanAttributeInfo[] dAttributes = new MBeanAttributeInfo[2];
 private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1];
 private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1];
 private MBeanInfo dMBeanInfo = null;

 public SimpleDynamic() {
  // 建立辅助信息
  buildDynamicMBeanInfo();
 }
 
 public Object getAttribute(String attribute_name)
   throws AttributeNotFoundException, MBeanException,
   ReflectionException {
  // 检查属性是否为空
  if (attribute_name == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "Attribute name cannot be null"),
     "Cannot invoke a getter of " + dClassName
       + " with null attribute name");
  }
  // 检查已知属性,调用已知方法
  if (attribute_name.equals("State")) {
   return getState();
  }
  if (attribute_name.equals("NbChanges")) {
   return getNbChanges();
  }
  // 如果属性不可识别,抛出异常
  throw (new AttributeNotFoundException("Cannot find " + attribute_name
    + " attribute in " + dClassName));
 }
 public void setAttribute(Attribute attribute)
   throws AttributeNotFoundException, InvalidAttributeValueException,
   MBeanException, ReflectionException {
  if (attribute == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "Attribute cannot be null"), "Cannot invoke a setter of "
     + dClassName + " with null attribute");
  }
  String name = attribute.getName();
  Object value = attribute.getValue();
  if (name == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "Attribute name cannot be null"),
     "Cannot invoke the setter of " + dClassName
       + " with null attribute name");
  }
  if (name.equals("State")) {
   if (value == null) {
    try {
     setState(null);
    } catch (Exception e) {
     throw (new InvalidAttributeValueException(
       "Cannot set attribute " + name + " to null"));
    }
   } else {
    try {
     if ((Class.forName("java.lang.String"))
       .isAssignableFrom(value.getClass())) {
      setState((String) value);
     } else {
      throw (new InvalidAttributeValueException(
        "Cannot set attribute " + name + " to a "
          + value.getClass().getName()
          + " object, String expected"));
     }
    } catch (ClassNotFoundException e) {
     e.printStackTrace();
    }
   }
  }
  // 由于"NbChanges" 属性是只读的,所以抛出异常
  else if (name.equals("NbChanges")) {
   throw (new AttributeNotFoundException("Cannot set attribute "
     + name + " because it is read-only"));
  } else {
   throw (new AttributeNotFoundException("Attribute " + name
     + " not found in " + this.getClass().getName()));
  }
 }
 public AttributeList getAttributes(String[] attributeNames) {
  if (attributeNames == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "attributeNames[] cannot be null"),
     "Cannot invoke a getter of " + dClassName);
  }
  AttributeList resultList = new AttributeList();
  if (attributeNames.length == 0)
   return resultList;
  for (int i = 0; i < attributeNames.length; i++) {
   try {
    Object value = getAttribute((String) attributeNames[i]);
    resultList.add(new Attribute(attributeNames[i], value));
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  return (resultList);
 }
 public AttributeList setAttributes(AttributeList attributes) {
  if (attributes == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "AttributeList attributes cannot be null"),
     "Cannot invoke a setter of " + dClassName);
  }
  AttributeList resultList = new AttributeList();
  if (attributes.isEmpty())
   return resultList;
  for (Iterator i = attributes.iterator(); i.hasNext();) {
   Attribute attr = (Attribute) i.next();
   try {
    setAttribute(attr);
    String name = attr.getName();
    Object value = getAttribute(name);
    resultList.add(new Attribute(name, value));
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  return (resultList);
 }
 /**
  * 设置操作
  */
 public Object invoke(String operationName, Object params[],
   String signature[]) throws MBeanException, ReflectionException {
  // 检查方法名是否为空
  if (operationName == null) {
   throw new RuntimeOperationsException(new IllegalArgumentException(
     "Operation name cannot be null"),
     "Cannot invoke a null operation in " + dClassName);
  }
  if (operationName.equals("reset")) {
   reset();
   return null;
  } else {
   throw new ReflectionException(new NoSuchMethodException(
     operationName), "Cannot find the operation "
     + operationName + " in " + dClassName);
  }
 }
 public MBeanInfo getMBeanInfo() {
  return (dMBeanInfo);
 }
 /*
  * ----------------------------------------------------- 下面是公共方法
  * -----------------------------------------------------
  */
 public String getState() {
  return state;
 }
 public void setState(String s) {
  state = s;
  nbChanges++;
 }
 public Integer getNbChanges() {
  return new Integer(nbChanges);
 }
 public void reset() {
  state = "initial state";
  nbChanges = 0;
  nbResets++;
 }
 public Integer getNbResets() {
  return new Integer(nbResets);
 }
 /**
  * 构造辅助信息,这里用了很多辅助类,具体看规范
  */
 private void buildDynamicMBeanInfo() {
  dAttributes[0] = new MBeanAttributeInfo("State", "java.lang.String",
    "State: state string.", true, true, false);
  dAttributes[1] = new MBeanAttributeInfo(
    "NbChanges",
    "java.lang.Integer",
    "NbChanges: number of times the State string has been changed.",
    true, false, false);
  Constructor[] constructors = this.getClass().getConstructors();
  dConstructors[0] = new MBeanConstructorInfo(
    "SimpleDynamic(): Constructs a SimpleDynamic object",
    constructors[0]);
  MBeanParameterInfo[] params = null;
  dOperations[0] = new MBeanOperationInfo(
    "reset",
    "reset(): reset State and NbChanges attributes to their initial values",
    params, "void", MBeanOperationInfo.ACTION);
  dMBeanInfo = new MBeanInfo(dClassName, dDescription, dAttributes,
    dConstructors, dOperations, new MBeanNotificationInfo[0]);
 }
}

agent代码:

import javax.management.*;
public class SimpleAgent {
 private MBeanServer server = null;
 ObjectName mbeanObjectName = null;
 String mbeanName = "SimpleDynamic";
 public SimpleAgent() {
  server = MBeanServerFactory.createMBeanServer();
  String domain = server.getDefaultDomain();
  try {
   mbeanObjectName = new ObjectName(domain + ":type=" + mbeanName);
   server.createMBean(mbeanName, mbeanObjectName);
  } catch (MalformedObjectNameException e) {
   e.printStackTrace();
   System.out.println("\nEXITING...\n");
   System.exit(1);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 public String getState() throws AttributeNotFoundException,
   InstanceNotFoundException, MBeanException, ReflectionException {
  return (String) server.getAttribute(mbeanObjectName, "State");
 }
 public Integer getNChange() throws AttributeNotFoundException,
   InstanceNotFoundException, MBeanException, ReflectionException {
  return (Integer) server.getAttribute(mbeanObjectName, "NbChanges");
 }
 public void printMBeanInfo() {
  MBeanInfo info = null;
  try {
   info = server.getMBeanInfo(mbeanObjectName);
  } catch (Exception e) {
   System.out.println("\t!!! Could not get MBeanInfo object for "
     + mbeanName + " !!!");
   e.printStackTrace();
   return;
  }
  System.out.println("\nCLASSNAME: \t" + info.getClassName());
  System.out.println("\nDESCRIPTION: \t" + info.getDescription());
  System.out.println("\nATTRIBUTES");
  MBeanAttributeInfo[] attrInfo = info.getAttributes();
  if (attrInfo.length > 0) {
   for (int i = 0; i < attrInfo.length; i++) {
    System.out.println(" ** NAME: \t" + attrInfo[i].getName());
    System.out.println(" DESCR: \t" + attrInfo[i].getDescription());
    System.out.println(" TYPE: \t" + attrInfo[i].getType()
      + "\tREAD: " + attrInfo[i].isReadable() + "\tWRITE: "
      + attrInfo[i].isWritable());
   }
  } else
   System.out.println(" ** No attributes **");
  System.out.println("\nCONSTRUCTORS");
  MBeanConstructorInfo[] constrInfo = info.getConstructors();
  for (int i = 0; i < constrInfo.length; i++) {
   System.out.println(" ** NAME: \t" + constrInfo[i].getName());
   System.out.println(" DESCR: \t" + constrInfo[i].getDescription());
   System.out.println(" PARAM: \t"
     + constrInfo[i].getSignature().length + " parameter(s)");
  }
  System.out.println("\nOPERATIONS");
  MBeanOperationInfo[] opInfo = info.getOperations();
  if (opInfo.length > 0) {
   for (int i = 0; i < opInfo.length; i++) {
    System.out.println(" ** NAME: \t" + opInfo[i].getName());
    System.out.println(" DESCR: \t" + opInfo[i].getDescription());
    System.out.println(" PARAM: \t"
      + opInfo[i].getSignature().length + " parameter(s)");
   }
  } else
   System.out.println(" ** No operations ** ");
  System.out.println("\nNOTIFICATIONS");
  MBeanNotificationInfo[] notifInfo = info.getNotifications();
  if (notifInfo.length > 0) {
   for (int i = 0; i < notifInfo.length; i++) {
    System.out.println(" ** NAME: \t" + notifInfo[i].getName());
    System.out
      .println(" DESCR: \t" + notifInfo[i].getDescription());
   }
  }
 }
 public void reset() throws InstanceNotFoundException, MBeanException,
   ReflectionException {
  server.invoke(mbeanObjectName, "reset", null, null);
 }
 public void setState(String state) {
  Attribute nbChangesAttribute = new Attribute("State", state);
  try {
   server.setAttribute(mbeanObjectName, nbChangesAttribute);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 public void setNChange(Integer nchange) {
  Attribute nbChangesAttribute = new Attribute("NbChanges", nchange);
  try {
   server.setAttribute(mbeanObjectName, nbChangesAttribute);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 public static void main(String[] args) {
  SimpleAgent agent = new SimpleAgent();
  try {
   agent.printMBeanInfo();
   System.out.println(agent.getState());
   System.out.println(agent.getNChange());
   agent.setState("come on, man");
//   agent.setNChange(new Integer(6));
   System.out.println(agent.getState());
   System.out.println(agent.getNChange());
   agent.reset();
   System.out.println(agent.getState());
   System.out.println(agent.getNChange());
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}
分享到:
评论

相关推荐

    jmx 实例 rmi mbean

    MBeans有三种主要类型:Standard MBeans、Dynamic MBeans和Open MBeans。Standard MBeans是预先定义了管理接口的类;Dynamic MBeans则是在运行时动态定义其管理接口;而Open MBeans允许使用通用的数据类型,便于不同...

    JMX实用例子详解(包括各种Mbean)

    2. **MBean Server**:这是JMX架构的核心,它负责注册和管理MBeans,处理MBean之间的交互,并提供给管理工具访问MBeans的接口。 3. **管理工具(Management Tools)**:这些工具可以是图形界面的,也可以是命令行的...

    customFuse:通用 JMX Mbeans 的 JON Fuse 插件扩展

    "通用 JMX Mbeans 的 JON Fuse 插件扩展" 表明此项目不仅关注于标准的 Mbeans,还支持广泛的自定义 Mbean 实例,从而增强了 JON 对复杂环境的适应性。这通常意味着用户可以通过编写或配置额外的插件模块,来管理和...

    jmx需要的jar包

    JMX支持三种类型的MBeans:Standard MBean、Dynamic MBean和Open MBean。 2. **MBean Server**:MBean Server是JMX架构中的核心组件,它负责注册MBeans、执行MBean操作、处理MBean之间的交互,并提供了一个集中式的...

    《jmx技术介绍》配套源代码

    JMX架构由管理代理(MBeans)、服务提供者接口(MBean Server)和管理客户端三部分组成。MBeans代表可管理的对象,它们可以是简单的数据点或复杂的系统服务。MBean Server是一个运行在Java虚拟机中的核心组件,它...

    jmx_examples.rar_Java 8_jmx_jmx examples_jmx main_jmx_examples

    - 压缩包中的例子可能包括创建不同类型的MBean(Standard MBean、Dynamic MBean等)、注册MBean到MBean Server、暴露和操作MBean属性、执行MBean方法以及处理MBean通知。 - 每个示例通常会展示如何创建一个简单的...

    jmx例子一则

    MBeans有三种类型:Standard MBean、Dynamic MBean和Open MBean,分别对应不同的定义和实现方式。 其次,JMX中的代理(MBeanServer)是管理的核心组件。它负责注册和管理MBeans,执行MBean的操作,并处理MBean之间...

    jmx-jvm配置

    2. **MBean Server**: MBean Server是JMX框架的核心,它负责注册、管理和查询MBeans,以及执行MBean的操作。 3. **Management Interface**: 这是MBean提供的接口,定义了可管理属性、操作和通知。 4. **JMX ...

    JMX IN ACTION(七)

    Model MBean与Standard和Dynamic MBeans的主要区别在于,开发人员不需要创建MBean类。Model MBean由`javax.management.modelmbean.RequiredModelMBean`类定义,它是JMX代理的一个必需部分。与Dynamic MBean类似,...

    JAVA JMX 学习资料

    MBeans是JMX的核心,分为三种类型:Standard MBeans、Dynamic MBeans和Open MBeans。Standard MBeans通过定义接口和实现类来定义管理接口;Dynamic MBeans可以在运行时动态地定义管理接口;Open MBeans允许更复杂的...

    JMX.rar_jmx

    MBeans有三种类型:Standard MBeans、Dynamic MBeans和Open MBeans,分别满足不同需求的灵活性和抽象程度。 - **MBean Server**:这是JMX架构的中心,它负责创建、注册和管理MBeans,以及处理MBean之间的交互。...

    JMX 入门 详细 教程

    通过MBeans、MBean Server、Notifications和Management Agents,JMX 创建了一个强大的管理框架,适用于各种规模和类型的Java应用。无论你是初学者还是经验丰富的开发者,理解并掌握JMX都将极大地提升你的应用程序...

    JMX、MXBean学习

    在JMX中,MBeans主要有三种类型:Standard MBeans、Dynamic MBeans和Model MBeans。Standard MBeans是预定义了管理接口的类,Dynamic MBeans则可以在运行时动态定义其管理接口,而Model MBeans是一种抽象层,可以将...

    JMX初学资料 初学者入门教程

    MBean主要有三种:Standard MBean、Dynamic MBean和Open MBean。Standard MBean通过接口定义其管理属性和操作,Dynamic MBean更灵活,可以在运行时动态定义其管理接口,而Open MBean则是为了跨Java平台的兼容性和互...

    JMX配置与使用

    有三种类型的MBeans:Standard MBeans、Dynamic MBeans和Model MBeans。Standard MBeans通过定义接口和实现类来定义其操作和属性。Dynamic MBeans则更灵活,可以在运行时动态定义管理接口。Model MBeans是最通用的,...

    JMXTools.jar和jmxri.jar下载

    在Java应用程序中,当你需要在运行时使用JMX服务,比如注册MBeans(Managed Beans),监听MBean属性变化或执行管理操作时,就需要包含`jmxri.jar`。 `jmxtools-1.2.1.jar`则是JMX工具集,提供了许多实用工具和API,...

    jmx学习资料

    MBeans分为三种类型:Standard MBean、Dynamic MBean和Open MBean。 2. **MBean Server**: MBean Server是JMX的核心组件,它负责注册MBeans、执行对MBeans的操作并处理MBeans之间的交互。它是管理域的中心,管理...

    jmx学习整理里1

    为了使用这些MBeans,我们需要一个MBeanServer,它是JMX的核心服务,负责注册MBean、执行MBean的操作和获取MBean的属性。`StandardAgent.java`通常会包含创建和注册MBean到MBeanServer的代码: ```java MBeanServer...

Global site tag (gtag.js) - Google Analytics