Comment se connecter à un programme Java sur localhost jvm en utilisant JMX?

Je devrais me connecter à un programme Java sur localhost jvm en utilisant JMX. En d’autres termes, je veux développer un client JMX pour configurer un programme Java sur localhost.

Nous utilisons quelque chose comme ce qui suit pour se connecter par programmation à nos serveurs JMX. Vous devez exécuter votre serveur avec les arguments suivants:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.ssl=false 

Pour vous connecter à une adresse particulière, vous devez append les arguments de machine virtuelle suivants:

 -Djava.rmi.server.hostname=ABCD 

Ensuite, vous pouvez vous connecter à votre serveur en utilisant le code client JMX comme suit:

 Ssortingng host = "localhost"; // or some ABCD int port = 1234; Ssortingng url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; JMXServiceURL serviceUrl = new JMXServiceURL(url); JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null); try { MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection(); // now query to get the beans or whatever Set beanSet = mbeanConn.queryNames(null, null); ... } finally { jmxConnector.close(); } 

Nous avons également du code qui peut se publier par programme sur un port particulier en dehors des arguments de la machine virtuelle, mais je pense que c’est plus que ce dont vous avez besoin.


En termes de connexion “by pid”, vous devez utiliser Java6 à partir de Java land à ma connaissance. Je n’ai pas utilisé le code suivant mais cela semble fonctionner.

 List vms = VirtualMachine.list(); for (VirtualMachineDescriptor desc : vms) { VirtualMachine vm; try { vm = VirtualMachine.attach(desc); } catch (AttachNotSupportedException e) { continue; } Properties props = vm.getAgentProperties(); Ssortingng connectorAddress = props.getProperty("com.sun.management.jmxremote.localConnectorAddress"); if (connectorAddress == null) { continue; } JMXServiceURL url = new JMXServiceURL(connectorAddress); JMXConnector connector = JMXConnectorFactory.connect(url); try { MBeanServerConnection mbeanConn = connector.getMBeanServerConnection(); Set beanSet = mbeanConn.queryNames(null, null); ... } finally { jmxConnector.close(); } } 

Je suis également l’auteur du package SimpleJMX, qui facilite le démarrage d’un serveur JMX et la publication de beans sur des clients distants.

 // create a new server listening on port 8000 JmxServer jmxServer = new JmxServer(8000); // start our server jmxServer.start(); // register our lookupCache object defined below jmxServer.register(lookupCache); jmxServer.register(someOtherObject); // stop our server jmxServer.stop(); 

Il possède également une interface client, mais pour le moment, aucun mécanisme ne permet de trouver les processus par PID – seules les combinaisons hôte / port sont sockets en charge (en 6/2012).

Pour clarifier, si vous souhaitez uniquement obtenir des statistiques JMX locales, vous n’avez pas besoin d’utiliser l’API à distance. Utilisez simplement java.lang.management.ManagementFactory :

 MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); memoryMXBean.getHeapMemoryUsage().getMax(); ... List beans = ManagementFactory.getMemoryPoolMXBeans(); ... 
 List vm = new ArrayList(); jvmList = new JVMListManager(); vm = jvmList.listActiveVM(); for (VirtualMachineDescriptor vmD : vm) { try { //importFrom is taking a process ID and returning a service url in a Ssortingng Format Ssortingng ServiceUrl = ConnectorAddressLink.importFrom(Integer.parseInt(vmD.id().sortingm())); JMXServiceURL jmxServiceUrl = new JMXServiceURL(ServiceUrl); jmxConnector = JMXConnectorFactory.connect(jmxServiceUrl, null); con = jmxConnector.getMBeanServerConnection(); CompilationMXBean compMXBean = ManagementFactory.newPlatformMXBeanProxy(con , ManagementFactory.COMPILATION_MXBEAN_NAME , CompilationMXBean.class); }catch(Exception e) { //Do Something } } protected List listActiveVM() { List vm = VirtualMachine.list(); return vm; } 

Cela nécessite que vous utilisiez l’argument jmxremote au démarrage de JVM pour le processus que vous essayez de lire. Être capable de le faire sans passer un argument jmxremote au démarrage. Vous devrez utiliser l’API attachée (applicable uniquement aux programmes utilisant Java 6 et supérieur.

Le plus simple signifie:

 import javax.management.Atsortingbute; import javax.management.AtsortingbuteList; import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import javax.management.ObjectName; // set a self JMX connection MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); // set the object name(s) you are willing to query, here a CAMEL JMX object ObjectName objn = new ObjectName("org.apache.camel:context=*,type=routes,name=\"route*\""); Set objectInstanceNames = mBeanServer.queryNames(objn, null); for (ObjectName on : objectInstanceNames) { // query a number of atsortingbutes at once AtsortingbuteList attrs = mBeanServer.getAtsortingbutes(on, new Ssortingng[] {"ExchangesCompleted","ExchangesFailed"}); // process atsortingbute values (beware of nulls...) // ... attrs.get(0) ... attrs.get(1) ... }