2013-06-25 40 views
2

我知道這是可能的使用JMX這樣調用Java類中的方法:調用方法通過Java JMX功能,其中的參數是一個ArrayList

try { JMXServiceURL serviceUrl = new JMXServiceURL(URL); 
     jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);   
     ObjectName objectName = new ObjectName("whatever"); 
     MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();  
     ret = (String)mbeanConn.invoke(objectName, methodName, paramsForInvoke, signitureForInvoke); 
    } 

如果我們想調用與參數的方法,我們需要將實際參數作爲Object數組傳遞,並將參數的類型作爲String數組傳遞。 因此,讓我們繼續上面的例子,讓我們說,如果我想通過所謂的SLIST一個String的ArrayList:

ArrayList<String> sList = new ArrayList<String>(); 
sList.add("kapd_be"); 
Object paramsForInvoke[] = {sList}; 
String signitureForInvoke[] = {ArrayList.class.getName()}; 

在這種情況下,一切工作正常,該方法被用適當的參數調用。 我可以在調用的方法中提取「kapd_be」字符串。

但是,如果我想讓參數成爲其他類的ArrayList讓我們說SortInfo(這是我寫的POJO類,包含幾個字段)代碼不會執行,我甚至不能調用方法,顯然沒有參數可以被提取。 這很奇怪,因爲唯一的區別是這樣的:

ArrayList<SortInfo> sList = new ArrayList<SortInfo>(); 

爲什麼?以及如何將SortInfo列表傳遞給該方法?

http://docs.oracle.com/javase/6/docs/api/javax/management/MBeanServerConnection.html

回答

3

泛型將類型,所以考慮您的操作參數作爲對象的列表。這意味着如果您有多個具有相同名稱和相同參數數量的操作,則需要修改某些內容。 (即列表的通用類型不能是唯一的區別)。所以列表可以在編譯時鍵入,但是在運行時,您定義爲SortInfos列表的內容實際上是對象列表,並且如果您傳入的列表中包含的對象不是SortInfos,那麼...... G.I.G.O.

我還建議您只需使用List<[Type]>作爲參數。如pr123指出的那樣,作爲參數傳遞的列表中的值需要可序列化,但前提是您的調用將被序列化以便到達目標MBeanServer。 (在下面的例子中,它不會)。

下面是一個例子:

接口

public interface GenericOpServiceMBean { 
    public String op(List<Date> dates); 
} 

默認地將Impl

public class GenericOpService implements GenericOpServiceMBean { 
    public String op(List<Date> dates) { 
     if(dates==null || dates.isEmpty()) return ""; 
     StringBuilder b = new StringBuilder(); 
     for(Date d: dates) { 
      b.append("\n\t").append(d); 
     } 
     return b.toString(); 
    } 
} 

測試

public class GenericArgsMBeanTest { 

    public static final MBeanServer SERVER = ManagementFactory.getPlatformMBeanServer(); 

    public static void main(String[] args) { 
     log("GenericArgsMBeanTest"); 
     try { 
      ObjectName on = new ObjectName("test:svc=Generic"); 
      SERVER.registerMBean(new GenericOpService(), on); 
      // invoking public String op(List<Date> dates); 
      List<Date> dates = new ArrayList<Date>(Arrays.asList(new Date[]{ 
        new Date(System.currentTimeMillis()), 
        new Date(System.currentTimeMillis()-1000), 
        new Date(System.currentTimeMillis()-10000) 
      })); 
      String result = (String)SERVER.invoke(on, "op", new Object[]{dates}, new String[]{List.class.getName()}); 
      // Note: We need to use the List class name, not ArrayList. 
      log("Result:\n" + result); 
     } catch (Exception ex) { 
      ex.printStackTrace(System.err); 
     } 
    } 


    public static void log(Object msg) { 
     System.out.println(msg); 
    } 
} 

輸出

GenericArgsMBeanTest 
Result: 

    Tue Jun 25 10:44:15 EDT 2013 
    Tue Jun 25 10:44:14 EDT 2013 
    Tue Jun 25 10:44:05 EDT 2013 
+0

實際執行的seriazable接口解決我的問題,但我接受你的答案的詳細解釋 –

+0

它逃過我通知你回答了你自己的問題... :) – Nicholas

0

的SortInfo類必須實現在運行時擦除序列化

相關問題