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.