Программный доступ к встроенным MBeans в Tomcat
Поэтому в основном я пытаюсь изменить код из этого руководства здесь: http://docs.oracle.com/javase/tutorial/jmx/remote/custom.html чтобы я мог получить доступ к MBeans из tomcat, которые описаны здесь: 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. Проблема в том, что когда я пытаюсь получить доступ к встроенным MBean-компонентам в Tomcat аналогичным образом, я сталкиваюсь с проблемой, что не могу найти интерфейс, определенный для любого из MBean-компонентов Tomcat. Я могу отслеживать MBeans из JConsole, но для этого мне нужно быть в состоянии сделать это из кода. Я где-то обнаружил, что это также может быть сделано с чем-то вроде этого:
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......
Я чувствую, что упускаю что-то довольно простое. Но информация по этому вопросу, как представляется, очень ограничена, и Google не сильно помог.
2 ответа
Я думаю, что в вашем втором фрагменте кода есть опечатка. Вы создали новое ObjectName для Catalina ThreadPool с именем mbeanName2, но когда вы пытаетесь получить атрибут "name", вы все еще используете mbeanName.
Так и должно быть:
ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName2, "name");
Кроме этого, ваш код должен работать нормально.
Сегодня у меня возникла та же проблема, что и Oz0234, описанный выше (с использованием TomEE 1.7.0 в Windows), но я некоторое время не понимал, почему решение ProxyBean вообще не работает ни с какими объектами Catalina.
Это работает с MBeanServerConnection.Метод getAttribute(objectName, attribute), но он не работает с использованием методов прокси-компонента. Я проверял и проверял много.
Наконец-то я выяснил, почему это происходит. Ответ заключается в том, что имена атрибутов в домене 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 в качестве имени получателя прокси-бина getS ImpleAttribute. К сожалению, это прямо противоположно тому, что описывает соглашение о присвоении имен для методов получения / установки bean-компонента.
Также я проверил другие атрибуты Tomcat Domain Objects (Catalina,Users), доступные в соединении JMX, и я также сравнил некоторые другие атрибуты. Если имя атрибута начинается с заглавной буквы, прокси бина работает. Если он начинается со строчной буквы, работает только метод 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");
}
Поэтому вам нужно обратить внимание, какой метод вы выберете.