【问题标题】:How do I invoke a DiagnosticCommandMBean programmatically?如何以编程方式调用 DiagnosticCommandMBean?
【发布时间】:2016-02-18 14:00:48
【问题描述】:

我想以编程方式运行 DiagnosticCommandMBean 的操作。

例如,我正在尝试使用不带参数的 vmFlags()。这是我的测试代码:

ObjectName name = new ObjectName("com.sun.management:type=DiagnosticCommand");
String port = System.getProperty("com.sun.management.jmxremote.port");
JMXServiceURL url =
        new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
MBeanInfo info = ManagementFactory.getPlatformMBeanServer().getMBeanInfo(name);

mbsc.invoke(
        name,
        info.getOperations()[13].getName(), // vmFlags
        null,
        null
    );

这给了我这个例外:

javax.management.ReflectionException
    at sun.management.DiagnosticCommandImpl.invoke(DiagnosticCommandImpl.java:233)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$240(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/1241281054.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
    at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
    at javax.management.remote.rmi.RMIConnectionImpl_Stub.invoke(Unknown Source)
    at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.invoke(RMIConnector.java:1022)

我做错了什么?

【问题讨论】:

  • 我能够通过调试来自 JMC 的调用并查看参数来完成这项工作。如果我将第 3 和第 4 个参数更改为以下参数,它可以工作 mbsc.invoke(name, info.getOperations()[13].getName(), new Object[] {null}, new String[]{"[Ljava.lang 。细绳;”} );'。我暂时不会将此作为答案,因为有人可以提供更完整的解释。
  • 从实现来看 - hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/…(最新的 8u 来源) - 它要求参数和签名为非空。将 args 3 和 4 更改为“new Object[0], new String[0]”应该也可以。

标签: java jmx mbeans


【解决方案1】:

在下面找到一个 sn-p,它显示了一种更简单的方法(而不是通过 RMI 连接到正在运行的 JVM)和 mbeanServer.invoke(...) 方法的正确语法。

ObjectName objectName =new ObjectName("com.sun.management:type=DiagnosticCommand");
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

String operationName = "vmFlags";
Object[] params = new Object[1];
String[] signature = new String[]{String[].class.getName()};

String result = (String) mbeanServer.invoke(objectName, operationName, 
                params, signature);

System.out.printf("%s: %s%n", operationName, result);

输出(实际值替换为...

vmFlags: -XX:...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2014-04-15
    相关资源
    最近更新 更多