跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

从黑箱到企业,第 2 部分: Bean,JMX 1.1 样式

Sing Li (westmakaha@yahoo.com), 咨询顾问和自由作家
Sing Li 的照片
Sing Li 是 Early Adopter JXTAProfessional Jini以及 Wrox Press 出版的许多其它书籍的作者。他定期为技术杂志撰稿,并且是 P2P 发展的积极传道者。Sing 是咨询顾问和自由作家,可以通过 westmakaha@yahoo.com与他联系。

简介: JMX 是受欢迎的新的 Java 平台标准扩展,它支持通过现代网络管理系统或企业管理系统对设备、应用程序和服务进行管理、控制和监控。本文是顾问兼受欢迎的作家 Sing Li 所著的关于 JMX 的三部分系列文章的第二篇,在本文中,作者演示了如何快速地将工具代码添加到基于 Java 的应用程序中。

发布日期: 2002 年 11 月 01 日
级别: 初级
访问情况 : 704 次浏览
评论: 


JMX 代理中模型 MBean 的运行时挂接

当您使用 ModelMBean 实现时,唯一必需的工作就是向 ModelMBean “封装器”实例提供合适的 ModelMBeanInfo 结构。清单 8 显示了来自 BaseModAgent 类的摘录:

清单 8. BaseModAgent.java 中 RequiredModelMBean 的运行时挂接

    try {
        ObjectName tpMBeanName = new ObjectName("MBean:name=ClickMeter");
        RequiredModelMBean modelmbean = 
          new   RequiredModelMBean(createMBeanInfo());
        modelmbean.setManagedResource(inManagedObj, "objectReference");
        server.registerMBean(modelmbean, tpMBeanName);
      } catch (Exception e) {
         System.out.println("Cannot register ClickMeter MBean!");
         e.printStackTrace();
         return;
      }
                

在清单 8 中,通过对本地 createMBeanInfo() 方法的调用对 javax.management.modelmbean.RequiredModelMBean 进行实例化。这种方法将创建描述由 MBean 公开的属性、操作和事件的元数据。另外请注意我们调用了 RequiredModelMBeansetManagedResource() 方法,向它提供 ClickMeterMod 这一“要封装的类”的引用。事实上,通过使用 JMX 参考实现,该引用还可以是 RMI 引用或 CORBA IOR - 允许使用 ModelMBean 方便地“工具化”远程资源。最后,请注意当我们在 MBeanServer 上调用 registerMBean() 时,我们注册的是 RequiredModelMBean 封装器实例,而不是非 MBean 的 ClickMeterMod 。图 6 显示了 RequiredModelMBean 在运行时期间是如何工作的:


图 6. RequiredModelMBean 的运行时操作
图 6. RequiredModelMBean 的运行时操作

图 6 说明了代理层如何只与 RequiredModelMBean 实例一起工作,而 RequiredModelMBean 实例又依次将属性的访问和操作映射到真正封装的 ClickMeterMod 类。这就减轻了对部分封装类的 JMX 相关性的任何要求。

填充 ModelMBean 元数据


实例化 RequiredModelMBean 实例时会向其提供元数据描述符。该描述符是 javax.management.modelmbean.ModelMBeanInfo 类的实例。它包含关于封装类公开的属性、操作和事件的全部信息(而且,更重要的是,还包含 RequiredModelMBean 应如何访问它们的信息)。 RequiredModelMBean 将在运行时生成它自己的元数据以代表封装类支持 DynamicMBean 接口。清单 9 显示了 createMBeanInfo() 方法中的这段代码:

清单 9. 在 createMBeanInfo() 方法中创建 ModelMBean 元数据

private ModelMBeanInfo createMBeanInfo() {
  Descriptor atDesc = new DescriptorSupport(new String[] {
                 "name=PanelValue",
                 "descriptorType=attribute",
                 "default=0",
                 "displayName=Value of the Panel",
                 "getMethod=getPanelValue",
                 "setMethod=setPanelValue"
                }
                );
    ModelMBeanAttributeInfo [] mmbai = new ModelMBeanAttributeInfo[1];
    mmbai[0] = new ModelMBeanAttributeInfo("PanelValue","java.lang.Integer",
      "The ClickMeter Value",  true,true, false, atDesc);
    ModelMBeanOperationInfo [] mmboi = new ModelMBeanOperationInfo[4];
    mmboi[0] = new ModelMBeanOperationInfo("incPanelValue", 
    "increment the meter value", null, "void", ModelMBeanOperationInfo.ACTION
    );
    mmboi[1] = new ModelMBeanOperationInfo("decPanelValue", 
    "decrement the meter value", null, "void", ModelMBeanOperationInfo.ACTION
    );
    mmboi[2] = new ModelMBeanOperationInfo("getPanelValue", 
    "getter for PanelValue", null,"Integer", ModelMBeanOperationInfo.INFO);
    MBeanParameterInfo [] mbpi = new MBeanParameterInfo[1];
    mbpi[0] =  new MBeanParameterInfo("inVal", "java.lang.Integer", 
      "value to set");
    mmboi[3] = new ModelMBeanOperationInfo("setPanelValue",
      "setter for PanelValue", mbpi, "void", ModelMBeanOperationInfo.ACTION);
    ModelMBeanConstructorInfo [] mmbci = new ModelMBeanConstructorInfo[1];
    mmbci[0] = new ModelMBeanConstructorInfo("ClickMeterMod", 
    "constructor for Model Bean Sample", null);
    return new ModelMBeanInfoSupport("dwjmxservice.basic.ClickMeterMod",
    "dw ModelMBean example", mmbai, mmbci, mmboi, null);
    }
                

在清单 9 中要注意的重要特性是 javax.management.modelmbean.ModelMBeanInfoSupport 类如何提供现成可用的 MBeanInfo 实现。事实上,整个方法都在处理这个支持类实例的实例化工作。要对它适当进行实例化,您必须提供封装类的完全限定名称以及描述,然后是指定将要公开的属性、构造器、操作和事件的四个附加参数。该方法的大多数代码主要是创建 ModelMBeanAttributeInfoModelMBeanConstructorInfoModelMBeanOperationInfo 数组,这些数组都是 ModelMBeanInfoSupport 类构造器的参数。请注意,用于 PanelValue 属性的 getter 方法和 setter 方法在操作的元数据中被再次定义。这是必需的,因为在封装类中不要求遵循词法模式(命名约定)。另外, RequiredModelMBean 信任所提供的元数据并且将不在封装类上执行额外的内省(如果引用是远程的或是基于 CORBA 的,那么这个操作甚至是不可能的)。

测试基于模型 MBean 的工具


使用 compile.bat 文件编译模型 MBean 示例,或者执行下列命令行:

javac -classpath 
        <jmx install dir>\lib\jmxri.jar;
        <jmx install dir>\lib\jmxtools.jar 
-d classes src\dwjmxservice\basic\*.java
                
      

使用 runmod.bat 文件运行模型 MBean 示例,或者从代码子目录执行下列命令行:

java -classpath 
        <jmx install dir>\lib\jmxri.jar;
        <jmx install dir>\lib\jmxtools.jar;
classes dwjmxservice.basic.ClickMeterMod
                
      

当您使用 HTTP 协议适配器测试这个 MBean 时,请注意从代理操作的角度来看,它几乎没什么不同。唯一的区别是,用于 PanelValue 的 getter 方法和 setter 方法操作还可以通过 Web 页面独立地使用。

不必使用 RequriedModelMBean 类对 JMX 执行“快速修改”,您可以通过对 DynamicMBean 接口直接编码来创建灵活得多的动态 MBean。


不用 RequiredModelMBean 来实现 DynamicMBean


将动态 MBean 工具添加到 ClickMeter 类是有关实现 javax.management.DynamicMBean 接口的所有方法的问题。我们创建名为 ClickMeterDynClickMeterInstrm 子类来做到这一点。清单 10 显示了 ClickMeterDyn 的代码:

清单 10. 实现 DynamicMBean 接口

package dwjmxservice.basic;
import javax.management.MBeanInfo;
import javax.management.DynamicMBean;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanOperationInfo;
public class ClickMeterDyn extends ClickMeterInstrm implements DynamicMBean {
  public ClickMeterDyn() {
  }
  public static void main(String[] args) {
   setLandF();
   ClickMeterDyn cms = new ClickMeterDyn();
    // can use standard MBean agent - same logic
    BaseStdAgent myAgent = new BaseStdAgent();
    myAgent.startAgent((Object) cms);
  }
// implements the dynamic MBean interface
public Object getAttribute(String inAttrName) {
  if (inAttrName.equals("PanelValue"))
               return ((Object) getPanelValue());
  else
           return null;
}
    public void setAttribute(Attribute attribute) {
      if (attribute.getName().equals("PanelValue"))
        setPanelValue((Integer)  attribute.getValue());
}
      public AttributeList getAttributes(String[] attributeNames) {
 AttributeList resultList = new AttributeList();
 for (int i=0 ; i<attributenames.length ; i++){
     try {
  resultlist.add(new attribute(attributenames[i],
                (object) getattribute( (string) attributenames[i])
                ));
     } catch (exception e) {
  e.printstacktrace();
     }
 }
 return(resultlist);
    }
    public attributelist setattributes(attributelist attributes) {
 attributelist resultlist="new" attributelist();
 for (int i="0;" i<attributes.size(); i++) {
     attribute attr="(Attribute)" attributes.get(i);
     try {
  setattribute(attr);
  string name="attr.getName();"
  resultlist.add(new attribute(name,
                (object) getattribute(name)));
     } catch(exception e) {
  e.printstacktrace();
     } }
 return(resultlist);
  }
  public object invoke(string opname, object params[], string signature[]) {
  if (opname.equals("incPanelValue")){
     incPanelValue();
 } else {
        if (opname.equals("decPanelValue")) {
            decPanelValue();
            }
      }
      return null;
  }
  public mbeaninfo getmbeaninfo() {
     mbeanattributeinfo [] mbai="new" mbeanattributeinfo[1];
      mbai[0]="new" mbeanattributeinfo("panelvalue",
      "java.lang.integer",
      "the panel value",
      true,
      true,
      false);
    mbeanconstructorinfo [] mbci="new" mbeanconstructorinfo[1];
    mbci[0]="new" mbeanconstructorinfo("clickmeterdyn", 
    "dynamic mbean click meter", null);
    mbeanoperationinfo [] mboi="new" mbeanoperationinfo[2];
    mboi[0]="new" mbeanoperationinfo("incpanelvalue", 
    "increment the meter value", null, "void", mbeanoperationinfo.action);
    mboi[1]="new" mbeanoperationinfo("decpanelvalue", 
    "decrement the meter value", null, "void", mbeanoperationinfo.action);
    return  new mbeaninfo("dwjmxservice.basic.clickmeterdyn",
       "mbean:click meter",
       mbai,
       mbci,
       mboi,
       null);
    }
  }
                

这里要注意的第一件事是, ClickMeterDyn 按要求的那样直接实现了 DynamicMBean 接口。我们还可以看到动态 MBean 通过对 getMBeanInfo() 方法的调用获得元数据信息。该方法的代码和我们在模型 MBean 例子中看到的很类似,但不完全一样。主要的区别是我们不必将 PanelValue 属性的 getter 方法和 setter 方法重新定义为公开的操作的一部分。

针对属性的 getter/setter 方法,将入站属性的名称与我们唯一的属性 PanelValue 进行比较,并相应地从 ClickPanelModel 读写值。 invoke() 方法通过比较入站操作的名称和我们所支持的两个操作( incPanelValuedecPanelValue )来进行处理。由于这些操作不使用入站参数且不返回值,因此进行匹配时我们只需调用 ClickMeterInstrm 类中相应的 incPanelValue() 方法或 decPanelValue() 方法。

测试动态 MBean


请注意,在清单 10 中 ClickMeterDyn 实际上使用了 BaseStdAgent 作为其 JMX 代理。这是因为使用动态 MBean 或标准 MBean 时从代理的角度来看,没有操作上的区别。同样,JMX 体系结构给予它最大的灵活性和可扩展性。

使用 compile.bat 文件编译动态 MBean 示例,或者执行下列命令行:

javac -classpath 
        <jmx install dir>\lib\jmxri.jar;
        <jmx install dir>\lib\jmxtools.jar 
-d classes src\dwjmxservice\basic\*.java
                
      

使用 rundyn.bat 文件运行动态 MBean 示例,或者在代码子目录中执行下列命令行:

java -classpath 
        <jmx install dir>\lib\jmxri.jar;
        <jmx install dir>\lib\jmxtools.jar;
classes dwjmxservice.basic.ClickMeterDyn
                
      

当您测试动态 MBean 时,请注意它是如何完全像标准 MBean 示例运行的。


结束语


当您将工具添加到现有的设备或软件服务中时,您通常可选择使用标准 MBean 或动态 MBean(包括模型 MBean)。标准 MBean 适合用于快速工具,但是不适合用于更改。动态 MBean 对于公开的属性、操作和事件的更改是有“弹性”的;但是, 对它们进行编程需要做更多的工作。使用模型 MBean 则取两家之长,支持自适应更改而无需大量编码和测试。

在本系列即将推出的最后一篇文章中,我们将了解 JMX MBean 和代理如何用于实际的网络管理系统。请静候下文!


参考资料

关于作者

Sing Li 的照片

Sing Li 是 Early Adopter JXTAProfessional Jini以及 Wrox Press 出版的许多其它书籍的作者。他定期为技术杂志撰稿,并且是 P2P 发展的积极传道者。Sing 是咨询顾问和自由作家,可以通过 westmakaha@yahoo.com与他联系。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology
ArticleID=162846
ArticleTitle=从黑箱到企业,第 2 部分: Bean,JMX 1.1 样式
publish-date=11012002
author1-email=westmakaha@yahoo.com
author1-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。