Search in sources :

Example 6 with RMIConnectorServer

use of javax.management.remote.rmi.RMIConnectorServer in project geode by apache.

the class ManagementAgent method configureAndStart.

/**
   * http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html #gdfvq
   * https://blogs.oracle.com/jmxetc/entry/java_5_premain_rmi_connectors
   * https://blogs.oracle.com/jmxetc/entry/building_a_remotely_stoppable_connector
   * https://blogs.oracle.com/jmxetc/entry/jmx_connecting_through_firewalls_using
   * https://blogs.oracle.com/jmxetc/entry/java_5_premain_rmi_connectors
   */
private void configureAndStart() throws IOException {
    // get the port for RMI Registry and RMI Connector Server
    final int port = this.config.getJmxManagerPort();
    final String hostname;
    final InetAddress bindAddr;
    if (StringUtils.isBlank(this.config.getJmxManagerBindAddress())) {
        hostname = SocketCreator.getLocalHost().getHostName();
        bindAddr = null;
    } else {
        hostname = this.config.getJmxManagerBindAddress();
        bindAddr = InetAddress.getByName(hostname);
    }
    String jmxManagerHostnameForClients = this.config.getJmxManagerHostnameForClients();
    if (StringUtils.isNotBlank(jmxManagerHostnameForClients)) {
        System.setProperty("java.rmi.server.hostname", jmxManagerHostnameForClients);
    }
    final SocketCreator socketCreator = SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.JMX);
    final boolean ssl = socketCreator.useSSL();
    if (logger.isDebugEnabled()) {
        logger.debug("Starting jmx manager agent on port {}{}", port, (bindAddr != null ? (" bound to " + bindAddr) : "") + (ssl ? " using SSL" : ""));
    }
    // RMISocketFactory.getDefaultSocketFactory();
    RMIClientSocketFactory rmiClientSocketFactory = ssl ? new SslRMIClientSocketFactory() : null;
    RMIServerSocketFactory rmiServerSocketFactory = new GemFireRMIServerSocketFactory(socketCreator, bindAddr);
    // Following is done to prevent rmi causing stop the world gcs
    System.setProperty("sun.rmi.dgc.server.gcInterval", Long.toString(Long.MAX_VALUE - 1));
    // Create the RMI Registry using the SSL socket factories above.
    // In order to use a single port, we must use these factories
    // everywhere, or nowhere. Since we want to use them in the JMX
    // RMI Connector server, we must also use them in the RMI Registry.
    // Otherwise, we wouldn't be able to use a single port.
    // Start an RMI registry on port <port>.
    registry = LocateRegistry.createRegistry(port, rmiClientSocketFactory, rmiServerSocketFactory);
    // Retrieve the PlatformMBeanServer.
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    // Environment map. why is this declared as HashMap?
    final HashMap<String, Object> env = new HashMap<String, Object>();
    // Manually creates and binds a JMX RMI Connector Server stub with the
    // registry created above: the port we pass here is the port that can
    // be specified in "service:jmx:rmi://"+hostname+":"+port - where the
    // RMI server stub and connection objects will be exported.
    // Here we choose to use the same port as was specified for the
    // RMI Registry. We can do so because we're using \*the same\* client
    // and server socket factories, for the registry itself \*and\* for this
    // object.
    final RMIServerImpl stub = new RMIJRMPServerImpl(port, rmiClientSocketFactory, rmiServerSocketFactory, env);
    // Create an RMI connector server.
    //
    // As specified in the JMXServiceURL the RMIServer stub will be
    // registered in the RMI registry running in the local host on
    // port <port> with the name "jmxrmi". This is the same name the
    // out-of-the-box management agent uses to register the RMIServer
    // stub too.
    //
    // The port specified in "service:jmx:rmi://"+hostname+":"+port
    // is the second port, where RMI connection objects will be exported.
    // Here we use the same port as that we choose for the RMI registry.
    // The port for the RMI registry is specified in the second part
    // of the URL, in "rmi://"+hostname+":"+port
    //
    // We construct a JMXServiceURL corresponding to what we have done
    // for our stub...
    final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + hostname + ":" + port + "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi");
    // Create an RMI connector server with the JMXServiceURL
    //
    // JDK 1.5 cannot use JMXConnectorServerFactory because of
    // http://bugs.sun.com/view_bug.do?bug_id=5107423
    // but we're using JDK 1.6
    jmxConnectorServer = new RMIConnectorServer(new JMXServiceURL("rmi", hostname, port), env, stub, mbs) {

        @Override
        public JMXServiceURL getAddress() {
            return url;
        }

        @Override
        public synchronized void start() throws IOException {
            try {
                registry.bind("jmxrmi", stub);
            } catch (AlreadyBoundException x) {
                final IOException io = new IOException(x.getMessage());
                io.initCause(x);
                throw io;
            }
            super.start();
        }
    };
    if (securityService.isIntegratedSecurity()) {
        shiroAuthenticator = new JMXShiroAuthenticator();
        env.put(JMXConnectorServer.AUTHENTICATOR, shiroAuthenticator);
        jmxConnectorServer.addNotificationListener(shiroAuthenticator, null, jmxConnectorServer.getAttributes());
        // always going to assume authorization is needed as well, if no custom AccessControl, then
        // the CustomAuthRealm
        // should take care of that
        MBeanServerWrapper mBeanServerWrapper = new MBeanServerWrapper();
        jmxConnectorServer.setMBeanServerForwarder(mBeanServerWrapper);
        registerAccessControlMBean();
    } else {
        /* Disable the old authenticator mechanism */
        String pwFile = this.config.getJmxManagerPasswordFile();
        if (pwFile != null && pwFile.length() > 0) {
            env.put("jmx.remote.x.password.file", pwFile);
        }
        String accessFile = this.config.getJmxManagerAccessFile();
        if (accessFile != null && accessFile.length() > 0) {
            // Lets not use default connector based authorization
            // env.put("jmx.remote.x.access.file", accessFile);
            // Rewire the mbs hierarchy to set accessController
            ReadOpFileAccessController controller = new ReadOpFileAccessController(accessFile);
            controller.setMBeanServer(mbs);
            mbs = controller;
        }
    }
    jmxConnectorServer.start();
    if (logger.isDebugEnabled()) {
        logger.debug("Finished starting jmx manager agent.");
    }
}
Also used : JMXServiceURL(javax.management.remote.JMXServiceURL) RMIServerImpl(javax.management.remote.rmi.RMIServerImpl) HashMap(java.util.HashMap) IOException(java.io.IOException) ReadOpFileAccessController(org.apache.geode.management.internal.unsafe.ReadOpFileAccessController) SocketCreator(org.apache.geode.internal.net.SocketCreator) SslRMIClientSocketFactory(javax.rmi.ssl.SslRMIClientSocketFactory) RMIClientSocketFactory(java.rmi.server.RMIClientSocketFactory) SslRMIClientSocketFactory(javax.rmi.ssl.SslRMIClientSocketFactory) RMIJRMPServerImpl(javax.management.remote.rmi.RMIJRMPServerImpl) MBeanServerWrapper(org.apache.geode.management.internal.security.MBeanServerWrapper) JMXShiroAuthenticator(org.apache.geode.internal.security.shiro.JMXShiroAuthenticator) RMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer) AlreadyBoundException(java.rmi.AlreadyBoundException) RMIServerSocketFactory(java.rmi.server.RMIServerSocketFactory) UnicastRemoteObject(java.rmi.server.UnicastRemoteObject) InetAddress(java.net.InetAddress) MBeanServer(javax.management.MBeanServer)

Example 7 with RMIConnectorServer

use of javax.management.remote.rmi.RMIConnectorServer in project jdk8u_jdk by JetBrains.

the class DeadListenerTest method main.

public static void main(String[] args) throws Exception {
    final ObjectName delegateName = MBeanServerDelegate.DELEGATE_NAME;
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    Noddy mbean = new Noddy();
    ObjectName name = new ObjectName("d:k=v");
    mbs.registerMBean(mbean, name);
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
    SnoopRMIServerImpl rmiServer = new SnoopRMIServerImpl();
    RMIConnectorServer cs = new RMIConnectorServer(url, null, rmiServer, mbs);
    cs.start();
    JMXServiceURL addr = cs.getAddress();
    assertTrue("No connections in new connector server", rmiServer.connections.isEmpty());
    JMXConnector cc = JMXConnectorFactory.connect(addr);
    MBeanServerConnection mbsc = cc.getMBeanServerConnection();
    assertTrue("One connection on server after client connect", rmiServer.connections.size() == 1);
    RMIConnectionImpl connection = rmiServer.connections.get(0);
    Method getServerNotifFwdM = RMIConnectionImpl.class.getDeclaredMethod("getServerNotifFwd");
    getServerNotifFwdM.setAccessible(true);
    ServerNotifForwarder serverNotifForwarder = (ServerNotifForwarder) getServerNotifFwdM.invoke(connection);
    Field listenerMapF = ServerNotifForwarder.class.getDeclaredField("listenerMap");
    listenerMapF.setAccessible(true);
    @SuppressWarnings("unchecked") Map<ObjectName, Set<?>> listenerMap = (Map<ObjectName, Set<?>>) listenerMapF.get(serverNotifForwarder);
    assertTrue("Server listenerMap initially empty", mapWithoutKey(listenerMap, delegateName).isEmpty());
    final AtomicInteger count1Val = new AtomicInteger();
    CountListener count1 = new CountListener(count1Val);
    mbsc.addNotificationListener(name, count1, null, null);
    WeakReference<CountListener> count1Ref = new WeakReference<>(count1);
    count1 = null;
    final AtomicInteger count2Val = new AtomicInteger();
    CountListener count2 = new CountListener(count2Val);
    NotificationFilterSupport dummyFilter = new NotificationFilterSupport();
    dummyFilter.enableType("");
    mbsc.addNotificationListener(name, count2, dummyFilter, "noddy");
    WeakReference<CountListener> count2Ref = new WeakReference<>(count2);
    count2 = null;
    assertTrue("One entry in listenerMap for two listeners on same MBean", mapWithoutKey(listenerMap, delegateName).size() == 1);
    Set<?> set = listenerMap.get(name);
    assertTrue("Set in listenerMap for MBean has two elements", set != null && set.size() == 2);
    assertTrue("Initial value of count1 == 0", count1Val.get() == 0);
    assertTrue("Initial value of count2 == 0", count2Val.get() == 0);
    Notification notif = new Notification("type", name, 0);
    mbean.sendNotification(notif);
    // Make sure notifs are working normally.
    long deadline = System.currentTimeMillis() + 2000;
    while ((count1Val.get() != 1 || count2Val.get() != 1) && System.currentTimeMillis() < deadline) {
        Thread.sleep(10);
    }
    assertTrue("New value of count1 == 1", count1Val.get() == 1);
    assertTrue("Initial value of count2 == 1", count2Val.get() == 1);
    // Make sure that removing a nonexistent listener from an existent MBean produces ListenerNotFoundException
    CountListener count3 = new CountListener();
    try {
        mbsc.removeNotificationListener(name, count3);
        assertTrue("Remove of nonexistent listener succeeded but should not have", false);
    } catch (ListenerNotFoundException e) {
    // OK: expected
    }
    // Make sure that removing a nonexistent listener from a nonexistent MBean produces ListenerNotFoundException
    ObjectName nonexistent = new ObjectName("foo:bar=baz");
    assertTrue("Nonexistent is nonexistent", !mbs.isRegistered(nonexistent));
    try {
        mbsc.removeNotificationListener(nonexistent, count3);
        assertTrue("Remove of listener from nonexistent MBean succeeded but should not have", false);
    } catch (ListenerNotFoundException e) {
    // OK: expected
    }
    // Now unregister our MBean, and check that notifs it sends no longer go anywhere.
    mbs.unregisterMBean(name);
    mbean.sendNotification(notif);
    Thread.sleep(200);
    assertTrue("New value of count1 == 1", count1Val.get() == 1);
    assertTrue("Initial value of count2 == 1", count2Val.get() == 1);
    // wait for the listener cleanup to take place upon processing notifications
    // waiting max. 5 secs
    int countdown = 50;
    while (countdown-- > 0 && (count1Ref.get() != null || count2Ref.get() != null)) {
        System.gc();
        Thread.sleep(100);
        System.gc();
    }
    // listener has been removed or the wait has timed out
    assertTrue("count1 notification listener has not been cleaned up", count1Ref.get() == null);
    assertTrue("count2 notification listener has not been cleaned up", count2Ref.get() == null);
    // Check that there is no trace of the listeners any more in ServerNotifForwarder.listenerMap.
    // THIS DEPENDS ON JMX IMPLEMENTATION DETAILS.
    // If the JMX implementation changes, the code here may have to change too.
    Set<?> setForUnreg = listenerMap.get(name);
    assertTrue("No trace of unregistered MBean: " + setForUnreg, setForUnreg == null);
}
Also used : ServerNotifForwarder(com.sun.jmx.remote.internal.ServerNotifForwarder) Set(java.util.Set) Notification(javax.management.Notification) Field(java.lang.reflect.Field) JMXConnector(javax.management.remote.JMXConnector) WeakReference(java.lang.ref.WeakReference) ListenerNotFoundException(javax.management.ListenerNotFoundException) MBeanServer(javax.management.MBeanServer) JMXServiceURL(javax.management.remote.JMXServiceURL) Method(java.lang.reflect.Method) ObjectName(javax.management.ObjectName) RMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NotificationFilterSupport(javax.management.NotificationFilterSupport) RMIConnectionImpl(javax.management.remote.rmi.RMIConnectionImpl) HashMap(java.util.HashMap) Map(java.util.Map) MBeanServerConnection(javax.management.MBeanServerConnection)

Example 8 with RMIConnectorServer

use of javax.management.remote.rmi.RMIConnectorServer in project jdk8u_jdk by JetBrains.

the class ConnectorStopDeadlockTest method main.

public static void main(String[] args) throws Exception {
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    RMIJRMPServerImplSub impl = new RMIJRMPServerImplSub();
    System.out.println("Creating connectorServer");
    connectorServer = new RMIConnectorServer(url, null, impl, mbs);
    System.out.println("Starting connectorServer");
    connectorServer.start();
    System.out.println("Making client");
    RMIConnection cc = impl.newClient(null);
    System.out.println("Closing client");
    cc.close();
    if (connectorServer.isActive()) {
        System.out.println("Stopping connectorServer");
        connectorServer.stop();
    }
    if (failure == null)
        System.out.println("TEST PASSED, no deadlock");
    else
        System.out.println("TEST FAILED");
}
Also used : JMXServiceURL(javax.management.remote.JMXServiceURL) RMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer) RMIConnection(javax.management.remote.rmi.RMIConnection) MBeanServer(javax.management.MBeanServer)

Example 9 with RMIConnectorServer

use of javax.management.remote.rmi.RMIConnectorServer in project tomcat70 by apache.

the class JmxRemoteLifecycleListener method createServer.

private JMXConnectorServer createServer(String serverName, String bindAddress, int theRmiRegistryPort, int theRmiServerPort, HashMap<String, Object> theEnv, RMIClientSocketFactory registryCsf, RMIServerSocketFactory registrySsf, RMIClientSocketFactory serverCsf, RMIServerSocketFactory serverSsf) {
    // Create the RMI registry
    Registry registry;
    try {
        registry = LocateRegistry.createRegistry(theRmiRegistryPort, registryCsf, registrySsf);
    } catch (RemoteException e) {
        log.error(sm.getString("jmxRemoteLifecycleListener.createRegistryFailed", serverName, Integer.toString(theRmiRegistryPort)), e);
        return null;
    }
    if (bindAddress == null) {
        bindAddress = "localhost";
    }
    String url = "service:jmx:rmi://" + bindAddress;
    JMXServiceURL serviceUrl;
    try {
        serviceUrl = new JMXServiceURL(url);
    } catch (MalformedURLException e) {
        log.error(sm.getString("jmxRemoteLifecycleListener.invalidURL", serverName, url), e);
        return null;
    }
    RMIConnectorServer cs = null;
    try {
        RMIJRMPServerImpl server = new RMIJRMPServerImpl(rmiServerPortPlatform, serverCsf, serverSsf, theEnv);
        cs = new RMIConnectorServer(serviceUrl, theEnv, server, ManagementFactory.getPlatformMBeanServer());
        cs.start();
        registry.bind("jmxrmi", server.toStub());
        log.info(sm.getString("jmxRemoteLifecycleListener.start", Integer.toString(theRmiRegistryPort), Integer.toString(theRmiServerPort), serverName));
    } catch (IOException e) {
        log.error(sm.getString("jmxRemoteLifecycleListener.createServerFailed", serverName), e);
    } catch (AlreadyBoundException e) {
        log.error(sm.getString("jmxRemoteLifecycleListener.createServerFailed", serverName), e);
    }
    return cs;
}
Also used : JMXServiceURL(javax.management.remote.JMXServiceURL) RMIJRMPServerImpl(javax.management.remote.rmi.RMIJRMPServerImpl) MalformedURLException(java.net.MalformedURLException) RMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer) AlreadyBoundException(java.rmi.AlreadyBoundException) Registry(java.rmi.registry.Registry) LocateRegistry(java.rmi.registry.LocateRegistry) IOException(java.io.IOException) RemoteException(java.rmi.RemoteException)

Example 10 with RMIConnectorServer

use of javax.management.remote.rmi.RMIConnectorServer in project cassandra by apache.

the class JMXServerUtils method createJMXServer.

/**
 * Creates a server programmatically. This allows us to set parameters which normally are
 * inaccessable.
 */
@SuppressWarnings("resource")
@VisibleForTesting
public static JMXConnectorServer createJMXServer(int port, String hostname, boolean local) throws IOException {
    Map<String, Object> env = new HashMap<>();
    InetAddress serverAddress = null;
    if (local) {
        serverAddress = InetAddress.getLoopbackAddress();
        System.setProperty("java.rmi.server.hostname", serverAddress.getHostAddress());
    }
    // Configure the RMI client & server socket factories, including SSL config.
    env.putAll(configureJmxSocketFactories(serverAddress, local));
    // configure the RMI registry
    Registry registry = new JmxRegistry(port, (RMIClientSocketFactory) env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE), (RMIServerSocketFactory) env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE), "jmxrmi");
    // Configure authn, using a JMXAuthenticator which either wraps a set log LoginModules configured
    // via a JAAS configuration entry, or one which delegates to the standard file based authenticator.
    // Authn is disabled if com.sun.management.jmxremote.authenticate=false
    env.putAll(configureJmxAuthentication());
    // Configure authz - if a custom proxy class is specified an instance will be returned.
    // If not, but a location for the standard access file is set in system properties, the
    // return value is null, and an entry is added to the env map detailing that location
    // If neither method is specified, no access control is applied
    MBeanServerForwarder authzProxy = configureJmxAuthorization(env);
    // Mark the JMX server as a permanently exported object. This allows the JVM to exit with the
    // server running and also exempts it from the distributed GC scheduler which otherwise would
    // potentially attempt a full GC every `sun.rmi.dgc.server.gcInterval` millis (default is 3600000ms)
    // For more background see:
    // - CASSANDRA-2967
    // - https://www.jclarity.com/2015/01/27/rmi-system-gc-unplugged/
    // - https://bugs.openjdk.java.net/browse/JDK-6760712
    env.put("jmx.remote.x.daemon", "true");
    // Set the port used to create subsequent connections to exported objects over RMI. This simplifies
    // configuration in firewalled environments, but it can't be used in conjuction with SSL sockets.
    // See: CASSANDRA-7087
    int rmiPort = COM_SUN_MANAGEMENT_JMXREMOTE_RMI_PORT.getInt();
    // We create the underlying RMIJRMPServerImpl so that we can manually bind it to the registry,
    // rather then specifying a binding address in the JMXServiceURL and letting it be done automatically
    // when the server is started. The reason for this is that if the registry is configured with SSL
    // sockets, the JMXConnectorServer acts as its client during the binding which means it needs to
    // have a truststore configured which contains the registry's certificate. Manually binding removes
    // this problem.
    // See CASSANDRA-12109.
    RMIJRMPServerImpl server = new RMIJRMPServerImpl(rmiPort, (RMIClientSocketFactory) env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE), (RMIServerSocketFactory) env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE), env);
    JMXServiceURL serviceURL = new JMXServiceURL("rmi", hostname, rmiPort);
    RMIConnectorServer jmxServer = new RMIConnectorServer(serviceURL, env, server, ManagementFactory.getPlatformMBeanServer());
    // If a custom authz proxy was created, attach it to the server now.
    if (authzProxy != null)
        jmxServer.setMBeanServerForwarder(authzProxy);
    jmxServer.start();
    ((JmxRegistry) registry).setRemoteServerStub(server.toStub());
    logJmxServiceUrl(serverAddress, port);
    return jmxServer;
}
Also used : RMIJRMPServerImpl(javax.management.remote.rmi.RMIJRMPServerImpl) HashMap(java.util.HashMap) RMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer) Registry(java.rmi.registry.Registry) InetAddress(java.net.InetAddress) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

RMIConnectorServer (javax.management.remote.rmi.RMIConnectorServer)12 JMXServiceURL (javax.management.remote.JMXServiceURL)9 RMIJRMPServerImpl (javax.management.remote.rmi.RMIJRMPServerImpl)7 IOException (java.io.IOException)5 AlreadyBoundException (java.rmi.AlreadyBoundException)4 Registry (java.rmi.registry.Registry)4 HashMap (java.util.HashMap)4 MBeanServer (javax.management.MBeanServer)4 InetAddress (java.net.InetAddress)3 MalformedURLException (java.net.MalformedURLException)3 RemoteException (java.rmi.RemoteException)3 LocateRegistry (java.rmi.registry.LocateRegistry)3 RMIServerSocketFactory (java.rmi.server.RMIServerSocketFactory)3 UnicastRemoteObject (java.rmi.server.UnicastRemoteObject)3 RMIClientSocketFactory (java.rmi.server.RMIClientSocketFactory)2 SslRMIClientSocketFactory (javax.rmi.ssl.SslRMIClientSocketFactory)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ServerNotifForwarder (com.sun.jmx.remote.internal.ServerNotifForwarder)1 WeakReference (java.lang.ref.WeakReference)1 Field (java.lang.reflect.Field)1