diff --git a/CHANGES.txt b/CHANGES.txt index 0a6268ccc9..367504ba17 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +2.1.22 + * Disable JMX rebinding (CASSANDRA-15653, CASSANDRA-16075) + 2.1.21 * Fix writing of snapshot manifest when the table has table-backed secondary indexes (CASSANDRA-10968) * Fix parse error in cqlsh COPY FROM and formatting for map of blobs (CASSANDRA-15679) diff --git a/src/java/org/apache/cassandra/service/CassandraDaemon.java b/src/java/org/apache/cassandra/service/CassandraDaemon.java index dc22834534..afd376e800 100644 --- a/src/java/org/apache/cassandra/service/CassandraDaemon.java +++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java @@ -23,7 +23,13 @@ import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.net.InetAddress; import java.net.UnknownHostException; -import java.rmi.registry.LocateRegistry; +import java.rmi.AccessException; +import java.rmi.AlreadyBoundException; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.Registry; +import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.util.List; import java.util.*; @@ -35,6 +41,7 @@ import javax.management.StandardMBean; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXServiceURL; import javax.management.remote.rmi.RMIConnectorServer; +import javax.management.remote.rmi.RMIJRMPServerImpl; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Iterables; @@ -97,23 +104,18 @@ public class CassandraDaemon try { RMIServerSocketFactory serverFactory = new RMIServerSocketFactoryImpl(); - LocateRegistry.createRegistry(Integer.valueOf(jmxPort), null, serverFactory); - - StringBuffer url = new StringBuffer(); - url.append("service:jmx:"); - url.append("rmi://localhost/jndi/"); - url.append("rmi://localhost:").append(jmxPort).append("/jmxrmi"); - - Map env = new HashMap(); - env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory); - - jmxServer = new RMIConnectorServer( - new JMXServiceURL(url.toString()), - env, - ManagementFactory.getPlatformMBeanServer() - ); + Map env = Collections.singletonMap(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory); + Registry registry = new JmxRegistry(Integer.valueOf(jmxPort), null, serverFactory, "jmxrmi"); + JMXServiceURL url = new JMXServiceURL(String.format("service:jmx:rmi://localhost/jndi/rmi://localhost:%s/jmxrmi", jmxPort)); + @SuppressWarnings("resource") + RMIJRMPServerImpl server = new RMIJRMPServerImpl(Integer.valueOf(jmxPort), + null, + (RMIServerSocketFactory) env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE), + env); + jmxServer = new RMIConnectorServer(url, env, server, ManagementFactory.getPlatformMBeanServer()); jmxServer.start(); + ((JmxRegistry)registry).setRemoteServerStub(server.toStub()); } catch (IOException e) { @@ -689,4 +691,48 @@ public class CassandraDaemon */ public boolean isRunning(); } + + + @SuppressWarnings("restriction") + private static class JmxRegistry extends sun.rmi.registry.RegistryImpl { + private final String lookupName; + private Remote remoteServerStub; + + JmxRegistry(final int port, + final RMIClientSocketFactory csf, + RMIServerSocketFactory ssf, + final String lookupName) throws RemoteException + { + super(port, csf, ssf); + this.lookupName = lookupName; + } + + @Override + public Remote lookup(String s) throws RemoteException, NotBoundException + { + return lookupName.equals(s) ? remoteServerStub : null; + } + + @Override + public void bind(String s, Remote remote) throws RemoteException, AlreadyBoundException, AccessException + { + } + + @Override + public void unbind(String s) throws RemoteException, NotBoundException, AccessException { + } + + @Override + public void rebind(String s, Remote remote) throws RemoteException, AccessException { + } + + @Override + public String[] list() throws RemoteException { + return new String[] {lookupName}; + } + + public void setRemoteServerStub(Remote remoteServerStub) { + this.remoteServerStub = remoteServerStub; + } + } }