I was writing something to aggregate a bunch of JMX exports today and was really annoyed at adding environment variables to the test runner. Luckily, Martin pointed me to a fantastic howto on exporting an MBeanServer without supplying env variables to the jvm when it starts up. I specialized what he did a bit to orient it towards testing stuff and wound up with:
package org.skife.test;
import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* Handy-dandy tool to help with JMX Testing
*/
public class JMXHelper
{
private static int port = -1;
/**
* Ensure JMX is all set up, returns port for JMX RMI Registry
*/
public static int initialize()
{
if (port != -1) return port;
try {
final ServerSocket sock = new ServerSocket();
sock.bind(new InetSocketAddress(0));
port = sock.getLocalPort();
sock.close();
LocateRegistry.createRegistry(port);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
String s = String.format("service:jmx:rmi:///jndi/rmi://:%d/jmxrmi", port);
JMXServiceURL url = new JMXServiceURL(s);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, null , mbs);
cs.start();
}
catch (Exception e) {
throw new IllegalStateException("Unable to bind JMX", e);
}
return port;
}
}
Now you can connect to it like normal:
String url = String.format("service:jmx:rmi:///jndi/rmi://localhost:%s/jmxrmi", port);
JMXConnector c = JMXConnectorFactory.connect(new JMXServiceURL(url));
and there is a JMXConnector to your "test" MBeanServer. As with most of JMX, it is kinda werid looking and obscure, but it works well :-)
Update: Martin pointed out that I could use less code. Changed.