Pierre-Henri
Pierre-Henri

Reputation: 1505

How to connect to a local JMX server by knowing the process id?

The motivation behind this is to manage local java services, using JMX, without something more heavyweight like the java service Wrapper.

Each service is started with -Dcom.sun.management.jmxremote which means that "The JVM is configured to work as a local (same-machine-only) JMX server." (see here for a good explaination).

I tried the Attach API, but decided against it since it is not bundled with Java SE6 and and integrating it with maven was not possible.

Upvotes: 1

Views: 6670

Answers (2)

Piotr Filip
Piotr Filip

Reputation: 66

@Tim Büthe

If ConnectorAddressLink.importFrom returns null, try loading management-agent.jar into VM.

For example with something like function startManagementAgent from https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/test/sun/management/jmxremote/bootstrap/TestManager.java

private static void startManagementAgent(String pid) throws IOException {
    /*
     * JAR file normally in ${java.home}/jre/lib but may be in ${java.home}/lib
     * with development/non-images builds
     */
    String home = System.getProperty("java.home");
    String agent = home + File.separator + "jre" + File.separator + "lib"
            + File.separator + "management-agent.jar";
    File f = new File(agent);
    if (!f.exists()) {
        agent = home + File.separator + "lib" + File.separator +
            "management-agent.jar";
        f = new File(agent);
        if (!f.exists()) {
            throw new RuntimeException("management-agent.jar missing");
        }
    }
    agent = f.getCanonicalPath();

    System.out.println("Loading " + agent + " into target VM ...");

    try {
        VirtualMachine.attach(pid).loadAgent(agent);
    } catch (Exception x) {
        throw new IOException(x.getMessage());
    }
}

Upvotes: 5

Pierre-Henri
Pierre-Henri

Reputation: 1505

I'm posting the question to share the solution since I haven't seen it here (Q&A). The key here is to use ConnectorAddressLink.importFrom(pid) to get the address.

public static MBeanServerConnection getLocalMBeanServerConnectionStatic(int pid) {
    try {
        String address = ConnectorAddressLink.importFrom(pid);
        JMXServiceURL jmxUrl = new JMXServiceURL(address);
        return JMXConnectorFactory.connect(jmxUrl).getMBeanServerConnection();
    } catch (IOException e) {
        throw new RuntimeException("Of course you still have to implement a good connection handling");
    }
}

Upvotes: 7

Related Questions