public class CustomRmiSocketFactory extends RMISocketFactory { private static RMISocketFactory delegate = RMISocketFactory.getDefaultSocketFactory(); public static void register(int customPort) throws IOException { RMISocketFactory.setSocketFactory(new CustomRmiSocketFactory(customPort)); } private final int customPort; private CustomRmiSocketFactory(int customPort) { this.customPort = customPort; } public Socket createSocket(String host, int port) throws IOException { return delegate.createSocket(host, port); } public ServerSocket createServerSocket(int port) throws IOException { // 0 means arbitrary port return delegate.createServerSocket(port!=0 ? port : customPort); } public int hashCode() { return customServerSocketPort; } public boolean equals(Object obj) { return (getClass() == obj.getClass() && customPort == ((CustomRmiSocketFactory) obj).customPort); } }
As fas as you ensure the register method is calles as early as possible in your application (e.g. in an static initializer in your main class) this works quite well. All RMI communication uses the predefined (server) port.
One unexpected and nasty thing happens when you use this in connection with JMX. If you start your application with the usual JMX options the JMX agent already initializes RMI and chooses a port befor any class of your application is loaded. In order to keep RMI only taking the defined port you either have to provice jour own JMX agent (wich first sets the factory) or start the JMX agent programatically in jour application (after setting the RMISocketFactory).
Keine Kommentare:
Kommentar veröffentlichen