Binding JMX on a dedicated address
Unfortunately in order to get JMX to bind to dedicated address (and not just 0.0.0.0) you have to jump through a few hoops. In order to save you some time – here is how you do it. Create your own RMISocketFactory that only creates server sockets on the specified address
public class RMIServerSocketFactoryImpl implements RMIServerSocketFactory {
private final InetAddress localAddress;
public RMIServerSocketFactoryImpl( final InetAddress pAddress ) {
localAddress = pAddress;
}
public ServerSocket createServerSocket(final int pPort) throws IOException {
return ServerSocketFactory.getDefault()
.createServerSocket(pPort, 0, localAddress);
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
return obj.getClass().equals(getClass());
}
public int hashCode() {
return RMIServerSocketFactoryImpl.class.hashCode();
}
}
Then create the naming service with that factory and create the RMI server using that naming service.
RMIServerSocketFactory serverFactory = new RMIServerSocketFactoryImpl(InetAddress.getByName(address));
LocateRegistry.createRegistry(namingPort, null, serverFactory);
StringBuffer url = new StringBuffer();
url.append("service:jmx:");
url.append("rmi://").append(address).append(':').append(protocolPort).append("/jndi/");
url.append("rmi://").append(address).append(':').append(namingPort).append("/connector");
Map env = new HashMap();
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
rmiServer = new RMIConnectorServer(
new JMXServiceURL(url.toString()),
env,
ManagementFactory.getPlatformMBeanServer()
);
rmiServer.start();
Why do some so simple things need to be so overly complicated?