java - 通过 java jmx 功能调用方法,其中参数是 ArrayList

标签 java connection parameter-passing jmx

我知道可以使用 jmx 调用 java 类中的方法,如下所示:

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);
    }

如果我们想调用带有参数的方法,我们需要将实际参数作为对象数组传递,并将参数的类型作为字符串数组传递。 那么让我们继续上面的例子,假设我想传递一个名为 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

最佳答案

泛型将在运行时被类型删除,因此请将您的操作参数视为对象列表。这意味着,如果您有多个具有相同名称和相同数量参数的操作,则需要进行某些修改。 (即列表的通用类型不能是唯一的区别)。因此,列表可以在编译时输入,但在运行时,您定义的 SortInfo 列表实际上是一个对象列表,如果您传入一个包含非 SortInfo 对象的列表,那么......G.I.G.O.

我还建议您简单地使用List<[Type]>作为你的参数。正如 pr123 所指出的,作为参数传递的列表中的值确实需要可序列化,但前提是您的调用将被序列化以到达目标 MBeanServer。 (在下面的示例中,不会)。

这是一个例子:

界面

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

实现

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

关于java - 通过 java jmx 功能调用方法,其中参数是 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17294586/

相关文章:

java - 是否可以使用来自 CA 的 keystore (该 keystore 用于签署 JAR,也可用于签署 CSR)以创建 SSL 证书

java - HSQLDB 无需 JDBC 即可访问数据库目录

c# - Azure Functions 连接监控

r - 依赖于默认参数的函数参数

java - 如何向java进程提供密码

parameters - 是否可以以某种方式创建类似 typeof 的函数

java - 无法获得超过一个随机数来匹配我的五个猜测

java - 如何在eclipse中的 Debug模式下将变量设置为null

java - 如何在 Eclipse 中找出某个方法是直接还是间接从另一个方法调用的?

android如何使用xmpp-smack在群聊中发送和接收图像和位置(使用 map )