Index: webapps/docs/config/listeners.xml =================================================================== --- webapps/docs/config/listeners.xml (revision 1489925) +++ webapps/docs/config/listeners.xml (working copy) @@ -433,6 +433,10 @@

The port to be used by the Platform JMX/RMI server.

+ +

Address of interface to be used by JMX/RMI server. This option is incompatible with com.sun.management.jmxremote.ssl = true.

+
+

Should any clients using these ports be forced to use local ports to connect to the the JMX/RMI server. This is useful when tunnelling Index: java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java =================================================================== --- java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java (revision 1489925) +++ java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java (working copy) @@ -21,7 +21,10 @@ import java.io.Serializable; import java.lang.management.ManagementFactory; import java.net.MalformedURLException; +import java.net.UnknownHostException; import java.net.Socket; +import java.net.ServerSocket; +import java.net.InetAddress; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.server.RMIClientSocketFactory; @@ -61,6 +64,7 @@ protected static final StringManager sm = StringManager.getManager(Constants.Package); + protected String rmiBindAddress = null; protected int rmiRegistryPortPlatform = -1; protected int rmiServerPortPlatform = -1; protected boolean rmiSSL = true; @@ -76,6 +80,22 @@ protected JMXConnectorServer csPlatform = null; /** + * Get the inet address on which the Platform RMI server is exported. + * @return The textual representation of inet address + */ + public String getRmiBindAddress() { + return rmiBindAddress; + } + + /** + * Set the inet address on which the Platform RMI server is exported. + * @param theRmiBindAddress The textual representation of inet address + */ + public void setRmiBindAddress(String theRmiBindAddress) { + rmiBindAddress = theRmiBindAddress; + } + + /** * Get the port on which the Platform RMI server is exported. This is the * port that is normally chosen by the RMI stack. * @return The port number @@ -189,11 +209,24 @@ // Configure SSL for RMI connection if required if (rmiSSL) { + if (rmiBindAddress != null) { + throw new IllegalStateException(sm.getString("jmxRemoteLifecycleListener.sslIncompatibleWithRmiBindAddress")); + } + csf = new SslRMIClientSocketFactory(); ssf = new SslRMIServerSocketFactory(ciphers, protocols, clientAuth); } + // Force server bind address if required + if (rmiBindAddress != null) { + try { + ssf = new RmiServerBindSocketFactory(InetAddress.getByName(rmiBindAddress)); + } catch (UnknownHostException e) { + log.error(sm.getString("jmxRemoteLifecycleListener.invalidRmiBindAddress", rmiBindAddress), e); + } + } + // Force the use of local ports if required if (useLocalPorts) { csf = new RmiClientLocalhostSocketFactory(csf); @@ -219,7 +252,7 @@ // Create the Platform server csPlatform = createServer("Platform", rmiRegistryPortPlatform, - rmiServerPortPlatform, env, + rmiServerPortPlatform, env, csf, ssf, ManagementFactory.getPlatformMBeanServer()); } else if (Lifecycle.STOP_EVENT == event.getType()) { @@ -229,11 +262,11 @@ private JMXConnectorServer createServer(String serverName, int theRmiRegistryPort, int theRmiServerPort, - HashMap theEnv, MBeanServer theMBeanServer) { + HashMap theEnv, RMIClientSocketFactory csf, RMIServerSocketFactory ssf, MBeanServer theMBeanServer) { // Create the RMI registry try { - LocateRegistry.createRegistry(theRmiRegistryPort); + LocateRegistry.createRegistry(theRmiRegistryPort, csf, ssf); } catch (RemoteException e) { log.error(sm.getString( "jmxRemoteLifecycleListener.createRegistryFailed", @@ -311,4 +344,18 @@ } + + public static class RmiServerBindSocketFactory + implements RMIServerSocketFactory { + private final InetAddress bindAddress; + + public RmiServerBindSocketFactory(InetAddress address) { + bindAddress = address; } + + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port, 0, bindAddress); + } + + } +} Index: java/org/apache/catalina/mbeans/LocalStrings.properties =================================================================== --- java/org/apache/catalina/mbeans/LocalStrings.properties (revision 1489925) +++ java/org/apache/catalina/mbeans/LocalStrings.properties (working copy) @@ -18,3 +18,5 @@ jmxRemoteLifecycleListener.destroyServerFailed=The JMX connector server could not be stopped for the {0} server jmxRemoteLifecycleListener.invalidURL=The JMX Service URL requested for the {0} server, "{1}", was invalid jmxRemoteLifecycleListener.start=The JMX Remote Listener has configured the registry on port {0} and the server on port {1} for the {2} server +jmxRemoteLifecycleListener.sslIncompatibleWithRmiBindAddress=rmiBindAddress is incompatible with com.sun.management.jmxremote.ssl = true +jmxRemoteLifecycleListener.invalidRmiBindAddress=Invalid RMI bind address "{0}"