[AMQ-7400] This closes #443

This commit is contained in:
jbonofre 2020-02-11 21:24:09 +01:00
commit 5838228333
2 changed files with 59 additions and 9 deletions

View File

@ -17,11 +17,17 @@
package org.apache.activemq.broker.jmx; package org.apache.activemq.broker.jmx;
import java.io.IOException; import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NoSuchObjectException; 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.registry.Registry;
import java.rmi.server.UnicastRemoteObject; import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -42,8 +48,9 @@ import javax.management.ObjectInstance;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.QueryExp; import javax.management.QueryExp;
import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL; import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.management.remote.rmi.RMIJRMPServerImpl;
import org.apache.activemq.Service; import org.apache.activemq.Service;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -98,6 +105,8 @@ public class ManagementContext implements Service {
private String brokerName; private String brokerName;
private String suppressMBean; private String suppressMBean;
private List<ObjectName> suppressMBeanList; private List<ObjectName> suppressMBeanList;
private Remote serverStub;
private RMIJRMPServerImpl server;
public ManagementContext() { public ManagementContext() {
this(null); this(null);
@ -140,20 +149,20 @@ public class ManagementContext implements Service {
MDC.put("activemq.broker", brokerName); MDC.put("activemq.broker", brokerName);
} }
try { try {
JMXConnectorServer server = connectorServer;
if (started.get() && server != null) { if (started.get() && server != null) {
LOG.debug("Starting JMXConnectorServer..."); LOG.debug("Starting JMXConnectorServer...");
try { try {
// need to remove MDC as we must not inherit MDC in child threads causing leaks // need to remove MDC as we must not inherit MDC in child threads causing leaks
MDC.remove("activemq.broker"); MDC.remove("activemq.broker");
server.start(); connectorServer.start();
serverStub = server.toStub();
} finally { } finally {
if (brokerName != null) { if (brokerName != null) {
MDC.put("activemq.broker", brokerName); MDC.put("activemq.broker", brokerName);
} }
connectorStarted.countDown(); connectorStarted.countDown();
} }
LOG.info("JMX consoles can connect to {}", server.getAddress()); LOG.info("JMX consoles can connect to {}", connectorServer.getAddress());
} }
} catch (IOException e) { } 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()); 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 { try {
if (registry == null) { if (registry == null) {
LOG.debug("Creating RMIRegistry on port {}", connectorPort); LOG.debug("Creating RMIRegistry on port {}", connectorPort);
registry = LocateRegistry.createRegistry(connectorPort); registry = new JmxRegistry(connectorPort);
} }
namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry"); namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry");
// Do not use the createMBean as the mx4j jar may not be in the // 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. // This is handy to use if you have a firewall and need to force JMX to use fixed ports.
rmiServer = ""+getConnectorHost()+":" + rmiServerPort; 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); LOG.debug("Created JMXConnectorServer {}", connectorServer);
} }
@ -664,4 +678,39 @@ public class ManagementContext implements Service {
public String getSuppressMBean() { public String getSuppressMBean() {
return suppressMBean; 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};
}
}
} }

View File

@ -41,6 +41,7 @@
!com.google.j2objc.annotations, !com.google.j2objc.annotations,
sun.misc*;resolution:=optional, sun.misc*;resolution:=optional,
sun.nio*;resolution:=optional, sun.nio*;resolution:=optional,
sun.rmi*;resolution:=optional,
javax.jmdns*;resolution:=optional, javax.jmdns*;resolution:=optional,
javax.resource*;resolution:=optional, javax.resource*;resolution:=optional,
javax.servlet*;resolution:=optional, javax.servlet*;resolution:=optional,