2016-02-18 2 views
1

Я бы запрограммировал операцию DiagnosticCommandMBean.Как я могу программно вызвать программу 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) 

Что я делаю неправильно?

+0

Я был в состоянии сделать эту работу отладки звонок от JMC и глядя на аргументах. Если я изменяю 3-й и 4-й аргументы на следующий, то работает mbsc.invoke (name, info.getOperations() [13] .getName(), new Object [] {null}, new String [] {"[Ljava.lang .String; "} ); '. На данный момент я не стану считать это ответом, поскольку кто-то может дать более полное объяснение. – doc

+0

Судя по реализации - http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/classes/sun/management/DiagnosticCommandImpl.java (последние источники 8u) - для этого требуются параметры и подпись должна быть не нулевой. Смена аргументов 3 и 4 на «новый объект [0], новая строка [0]» должна также работать. – Klara

ответ

1

Найдите ниже фрагмент, который показывает более простой способ (вместо подключения через 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:... 
Смежные вопросы