以编程方式访问Tomcat中的内置MBean

以编程方式访问Tomcat中的内置MBean,tomcat,jmx,mbeans,Tomcat,Jmx,Mbeans,基本上,我在这里尝试修改本教程中的代码: 因此,我可以从tomcat访问MBean,如下所述: 从代码中访问JMXbean java.lang:type=Memory没有问题,因为它的接口是在java.lang中定义的。下面是这方面的代码示例: ObjectName mbeanName = new ObjectName("java.lang:type=Memory"); MemoryMXBean mxbeanProxy2 = JMX.newMXBeanProxy(mbsc, mb

基本上,我在这里尝试修改本教程中的代码: 因此,我可以从tomcat访问MBean,如下所述:

从代码中访问JMXbean 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");
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").
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");
}
但这给了我一个例外: 线程“main”javax.management.AttributeNotFoundException中的异常:没有这样的属性:com.sun.jmx.mbeanserver上的名称


我觉得我错过了一些基本的东西。但有关这方面的信息似乎非常有限,谷歌也没有提供多少帮助

我认为您的第二段代码中有一个输入错误。您为Catalina线程池创建了一个名为mbeanName 2的新ObjectName,但当您尝试检索属性“name”时,仍在使用mbeanName

因此,它应该是:

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

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

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

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

我终于找到了发生这种情况的原因。答案是,Catalina域中的属性名称以小写字母开头,而其他域(java.lang、java.nio、openejb等)中的属性名称以大写字母开头,如下所述:

我摘录了最相关的部分:

MyMXBean proxy = JMX.newMXBeanProxy(mbs, name, MyMXBean.class);
例如,假设MyMXBean如下所示:

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName, "name");
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").
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");
}
您可以看到上面的示例,该属性的名称以大写字母“s”impleAttribute开头,而代理bean getter名称以simpleAttribute开头。不幸的是,这与bean的getter/setter命名约定描述的恰恰相反

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

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName, "name");
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").
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");
}

因此,您需要注意选择哪种方法。

那么,只要纠正这个打字错误就行了吗?一旦我能证实这一点,我会接受你的回答。。。