This is an automated email from the ASF dual-hosted git repository. jbonofre pushed a commit to branch activemq-5.15.x in repository https://gitbox.apache.org/repos/asf/activemq.git
commit c29244931d54affaceabb478b3a52d9b74f5d543 Author: Jonathan Gallimore <[email protected]> AuthorDate: Thu Jan 30 15:00:48 2020 +0000 Provide RMI registry implementation to prevent re-bind --- .../activemq/broker/jmx/ManagementContext.java | 67 +++++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java index a1800db..07111bc 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/ManagementContext.java @@ -17,11 +17,17 @@ package org.apache.activemq.broker.jmx; import java.io.IOException; +import java.lang.management.ManagementFactory; import java.lang.reflect.Method; +import java.rmi.AccessException; +import java.rmi.AlreadyBoundException; import java.rmi.NoSuchObjectException; -import java.rmi.registry.LocateRegistry; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -42,8 +48,9 @@ import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.QueryExp; import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnectorServer; +import javax.management.remote.rmi.RMIJRMPServerImpl; import org.apache.activemq.Service; import org.slf4j.Logger; @@ -98,6 +105,8 @@ public class ManagementContext implements Service { private String brokerName; private String suppressMBean; private List<ObjectName> suppressMBeanList; + private Remote serverStub; + private RMIJRMPServerImpl server; public ManagementContext() { this(null); @@ -140,20 +149,20 @@ public class ManagementContext implements Service { MDC.put("activemq.broker", brokerName); } try { - JMXConnectorServer server = connectorServer; if (started.get() && server != null) { LOG.debug("Starting JMXConnectorServer..."); try { // need to remove MDC as we must not inherit MDC in child threads causing leaks MDC.remove("activemq.broker"); - server.start(); + connectorServer.start(); + serverStub = server.toStub(); } finally { if (brokerName != null) { MDC.put("activemq.broker", brokerName); } connectorStarted.countDown(); } - LOG.info("JMX consoles can connect to {}", server.getAddress()); + LOG.info("JMX consoles can connect to {}", connectorServer.getAddress()); } } catch (IOException e) { LOG.warn("Failed to start JMX connector {}. Will restart management to re-create JMX connector, trying to remedy this issue.", e.getMessage()); @@ -546,8 +555,9 @@ public class ManagementContext implements Service { try { if (registry == null) { LOG.debug("Creating RMIRegistry on port {}", connectorPort); - registry = LocateRegistry.createRegistry(connectorPort); + registry = new JmxRegistry(connectorPort); } + namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry"); // Do not use the createMBean as the mx4j jar may not be in the @@ -570,10 +580,14 @@ public class ManagementContext implements Service { // This is handy to use if you have a firewall and need to force JMX to use fixed ports. rmiServer = ""+getConnectorHost()+":" + rmiServerPort; } - String serviceURL = "service:jmx:rmi://" + rmiServer + "/jndi/rmi://" +getConnectorHost()+":" + connectorPort + connectorPath; - JMXServiceURL url = new JMXServiceURL(serviceURL); - connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, environment, mbeanServer); + final Map<String,Object> env = new HashMap<>(); + server = new RMIJRMPServerImpl(connectorPort, null, null, environment); + + final String serviceURL = "service:jmx:rmi://" + rmiServer + "/jndi/rmi://" +getConnectorHost()+":" + connectorPort + connectorPath; + final JMXServiceURL url = new JMXServiceURL(serviceURL); + + connectorServer = new RMIConnectorServer(url, env, server, ManagementFactory.getPlatformMBeanServer()); LOG.debug("Created JMXConnectorServer {}", connectorServer); } @@ -664,4 +678,39 @@ public class ManagementContext implements Service { public String getSuppressMBean() { return suppressMBean; } + + /* + * Better to use the internal API than re-invent the wheel. + */ + @SuppressWarnings("restriction") + private class JmxRegistry extends sun.rmi.registry.RegistryImpl { + public static final String LOOKUP_NAME = "jmxrmi"; + + public JmxRegistry(int port) throws RemoteException { + super(port); + } + + @Override + + public Remote lookup(String s) throws RemoteException, NotBoundException { + return LOOKUP_NAME.equals(s) ? serverStub : 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[] {LOOKUP_NAME}; + } + } }
