I found this question on Stack Overflow about how to connect to a locally running process and read JMX metrics. I thought I’d explain a little bit more in detail here on the blog. The steps involved are:
- Try to get the JMX Service URL for the local JMX agent.
- If you couldn’t, try to start the local JMX agent.
- Open an MBeanServerConnection to the local JMX agent.
- Do whatever MBean-ish stuff you were planning on doing, for example reading attributes.
This is pretty much as simple as it sounds. Let’s do them in order.
Getting the Service URL
When the local management agent is started, it publishes the service URL (which also contains the serialized stub for communication – take a look at the URL, it’s really quite funny) in a well known location. This can be retrieved by using the sun.management.ConnectorAddressLink class like this:
private static JMXServiceURL getLocalStubServiceURLFromPID(int pid)
throws IOException {
String address = ConnectorAddressLink.importFrom(pid);
if (address != null) {
return new JMXServiceURL(address);
}
return null;
}
If you didn’t get any service url, then the local management agent was not started.
Starting the Local Management Agent
Starting the local management agent can be done in various ways. In late versions of the JDK this is quite easily done. I am only going to show you the simple way today. In older you might need to resort to the attach command to load java agents (VirtualMachine vm = VirtualMachine.attach(pid).loadAgent(<path to management-agent.jar>,”com.sun.management.jmxremote”)).
To start the local agent, we simply execute the diagnostic command for starting it:
…
executeCommandForPID(vm, pid, “ManagementAgent.start_local”);
…
private static void executeCommandForPID(VirtualMachine vm, String pid,
String cmd) throws IOException {
HotSpotVirtualMachine hsvm = (HotSpotVirtualMachine) vm;
hsvm.executeJCmd(cmd);
}
Opening the MBeanServer Connection
This, as well as doing the MBeany things you want to do once you have the connection, is done just as you would normally do it:
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection connection = jmxc.getMBeanServerConnection();
Getting attributes:
connection.getAttribute(“java.lang:type=Memory”, “HeapMemoryUsage”);
Summary
- Hooking up to the local management agent is quite easy.
- There are valuable metrics that can be collected.
- Here is a full example getting the JVM CPU load as well as used heap.
Dear Marcus,
Thank you for this nice blog and the working example! It got me started quickly.
I have a question though: will the com.sun.tools* apis still be available under JDK9?
Many thanks in advance for your answer,
Vito B.