2013-07-03 22 views
3

所以基本上我試圖修改從本教程這裏的代碼:http://docs.oracle.com/javase/tutorial/jmx/remote/custom.html ,這樣我可以從Tomcat訪問的MBean此處所描述:http://wiki.apache.org/tomcat/FAQ/Monitoring訪問內置的MBean在Tomcat中編程

沒有訪問JMX Bean的問題java.lang:type =內存代碼,因爲它的接口是在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中的內置MBeans時,遇到了無法找到爲任何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 ......

我覺得我錯過了一些相當基本的東西。但有關這方面的信息似乎非常有限,谷歌沒有多大幫助。

回答

2

我認爲在你的第二段代碼中有一個錯字。您創建了卡塔利娜線程池一個新的對象名叫做mbeanName2,但是當你試圖要獲得的屬性「名」,你還在使用mbeanName

所以它應該是:

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

其他,你的代碼應該很好地工作。

+0

所以只修復這個錯字它應該工作?一旦我可以驗證這一點,我會接受你的答案... – Oz0234

1

今天我有什麼上述Oz0234(在Windows上使用TomEE 1.7.0)相同的問題,但我不明白的,而爲什麼ProxyBean解決方案不與任何物體卡特琳娜在所有的工作。

它適用於MBeanServerConnection。 getAttribute(objectName,attribute)方法但它不起作用使用代理bean方法。我已經檢查和測試了很多。

最後我找到了爲什麼發生這種情況。答案是:在卡塔利娜域屬性名稱以小寫字母在其他領域(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」開頭,作爲代理bean getter名稱的實現屬性獲得S落實。不幸的是,這與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"); 
} 

所以,你需要支付你選擇哪種方法的關注。

+0

這是非常正確的。 –