4

基本上我正在尝试在此处修改本教程中的代码:http: //docs.oracle.com/javase/tutorial/jmx/remote/custom.html ,以便我可以从此处描述的tomcat访问MBean:http ://wiki.apache.org/tomcat/FAQ/Monitoring

从代码中访问 JMX Bean java.lang:type=Memory 没有问题,因为它的接口是在 java.lang 中定义的。这是它的代码示例:

    ObjectName mbeanName = new ObjectName("java.lang:type=Memory");
    MemoryMXBean mxbeanProxy2 = JMX.newMXBeanProxy(mbsc, mbeanName, MemoryMXBean.class, true);
    MemoryUsage memUsage = mxbeanProxy2.getHeapMemoryUsage();
    echo("\nMemory Utilization: " + (memUsage.getUsed()/(double)memUsage.getMax()) * 100 +  "%");

这里的mbsc 是MBeanServerConnection 的一个实例。问题是,当我尝试以类似的方式访问 tomcat 中的内置 MBean 时,我遇到了找不到为任何 tomcat MBean 定义的任何接口的问题。我可以从 JConsole 监视 MBean,但为此我需要能够从代码中执行此操作。我在某处发现它也可以通过以下方式完成:

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName, "name");

但这给了我这个异常:线程“main”javax.management.AttributeNotFoundException中的异常:没有这样的属性:com.sun.jmx.mbeanserver的名称......

我觉得我错过了一些相当基本的东西。但是这方面的信息似乎非常有限,谷歌并没有太大帮助。

4

2 回答 2

2

我认为您的第二段代码中有错字。您为 Catalina ThreadPool 创建了一个名为mbeanName2的新 ObjectName ,但是当您尝试检索属性“name”时,您仍在使用mbeanName

所以应该是:

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName2, "name");

除此之外,您的代码应该可以正常工作。

于 2013-07-03T20:52:23.663 回答
2

今天我遇到了与上述 Oz0234 相同的问题(在 Windows 上使用 TomEE 1.7.0),但我有一段时间不明白为什么 ProxyBean 解决方案根本不适用于任何 Catalina 对象。

它与 MBeanServerConnection 一起工作。getAttribute (objectName, attribute) 方法,但使用代理 bean 方法不起作用。我已经检查和测试了很多。

最后我找到了为什么会发生这种情况。答案是Catalina 域中的属性名称以小写字母开头,而其他域(java.lang、java.nio、openejb、...)中的属性名称以大写字母开头,如下所述:http:// docs.oracle.com/javase/7/docs/api/javax/management/JMX.html

我提取了最相关的部分:

MyMXBean proxy = JMX.newMXBeanProxy(mbs, name, MyMXBean.class);

例如,假设 MyMXBean 看起来像这样:

public interface MyMXBean {
  public String getSimpleAttribute();
  public void setSimpleAttribute(String value);
  public MemoryUsage getMappedAttribute();
  public void setMappedAttribute(MemoryUsage memoryUsage);
  public MemoryUsage someOperation(String param1, MemoryUsage param2);
}

Then proxy.getSimpleAttribute() will result in a call to
mbs.getAttribute(name, "SimpleAttribute").

可以看到上面的例子,属性名以大写字母“ S ” impleAttribute作为代理bean getter name get SimpleAttribute。不幸的是,这与 bean 的 getter/setter 命名约定所描述的完全相反。

我还检查了 JMX 连接上可用的其他 Tomcat 域对象(Catalina,Users)属性,并且我还比较了其他一些属性。如果属性名称以大写字母开头,则 bean 代理工作。如果它以小写字母开头,则只有 getAttribute 方法有效,如下所示:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
try(JMXConnector jmxc = JMXConnectorFactory.connect(url)) {
  MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
  ObjectName mbeanName = new ObjectName("Catalina:type=Manager,context=/,host=localhost");
  Object value = mbsc.getAttribute(mbeanName, "activeSessions");
}

所以你需要注意你选择哪种方法。

于 2015-11-08T23:24:19.080 回答