I should connect to a java program on localhost jvm using JMX. In other words I want to develop a JMX client to config a java program on localhost.
Don't recommend using JConsole! JConsole is not suitable because it is general JMX client and have negative effect on main program performance.
Samples on oracle site use RMIConnector and host:port params but I don't know: where should set jmx port?
JConsole have an option to connect to java processes by PID. But I don't find any method in JMX api that have PID as input param.
A common way to enable local JMX access on these JVMs is to include the -Dcom. sun. management. jmxremote option on the command line when you start the JVM.
The Java virtual machine (Java VM) has built-in instrumentation that enables you to monitor and manage it using the Java Management Extensions (JMX) technology. These built-in management utilities are often referred to as out-of-the-box management tools for the Java VM.
— properties. Use an URL such as service:jmx:rmi:///… to let Java pick the IP and port for you (randomly or based on system properties). Use an URL such as service:jmx:rmi://0.0.0.0:1234 to bind port 1234 on all interfaces.
We use something like the following to programatically connect to our JMX servers. You should run your server with something like the following arguments:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.ssl=false
To bind to a particular address you'll need to add the following VM arguments:
-Djava.rmi.server.hostname=A.B.C.D
Then you can connect to your server using JMX client code like the following:
String host = "localhost"; // or some A.B.C.D int port = 1234; String 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<ObjectName> beanSet = mbeanConn.queryNames(null, null); ... } finally { jmxConnector.close(); }
We also have code that can programatically publish itself to a particular port outside of the VM arguments but that's more fu than you need I think.
In terms of connecting "by pid", you need to be using Java6 to do it from Java land as far as I know. I've not used the following code but it seems to work.
List<VirtualMachineDescriptor> vms = VirtualMachine.list(); for (VirtualMachineDescriptor desc : vms) { VirtualMachine vm; try { vm = VirtualMachine.attach(desc); } catch (AttachNotSupportedException e) { continue; } Properties props = vm.getAgentProperties(); String 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<ObjectName> beanSet = mbeanConn.queryNames(null, null); ... } finally { jmxConnector.close(); } }
I've also the author of SimpleJMX package which makes it easy to start a JMX server and publish beans to remote clients.
// 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();
It does have a client interface as well but right now it doesn't have any mechanisms to find processes by PID -- only host/port combinations are supported (in 6/2012).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With