Example usage for javax.management.remote JMXConnectorServer AUTHENTICATOR

List of usage examples for javax.management.remote JMXConnectorServer AUTHENTICATOR

Introduction

In this page you can find the example usage for javax.management.remote JMXConnectorServer AUTHENTICATOR.

Prototype

String AUTHENTICATOR

To view the source code for javax.management.remote JMXConnectorServer AUTHENTICATOR.

Click Source Link

Document

Name of the attribute that specifies the authenticator for a connector server.

Usage

From source file:org.wso2.carbon.core.init.JMXServerManager.java

/**
 * The method to start JMX service.//  w ww.  j  a v a2 s .  c  o m
 *
 * @throws ServerException If an error occurs while starting the RMI server
 */
public void startJMXService() throws ServerException {

    //File path for the jmx config file.
    String filePath = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "jmx.xml";
    boolean startJMXServer = false;

    File jmxConfigFile = new File(filePath);

    //Check whether jmx.xml file exists
    if (jmxConfigFile.exists()) {
        //Read jmx.xml file.
        parseJMXConfigXML(filePath);
        startJMXServer = jmxProperties.isStartServer();
        if (!startJMXServer) {
            return;
        }
    }

    int rmiRegistryPort = jmxProperties.getRmiRegistryPort();
    if (rmiRegistryPort == -1) {
        throw new RuntimeException(
                "RMIRegistry port has not been properly defined in the " + "jmx.xml or carbon.xml files");
    }
    MBeanServer mbs = ManagementFactory.getMBeanServer();
    String jmxURL;
    try {
        try {
            rmiRegistry = LocateRegistry.createRegistry(rmiRegistryPort);
        } catch (Throwable ignored) {
            log.error("Could not create the RMI local registry", ignored);
        }

        String hostName;
        //If 'startRMIServer' element in jmx.xml file set to true and 'HostName' element
        // value that file is not null.
        if (startJMXServer && jmxProperties.getHostName() != null) {
            hostName = jmxProperties.getHostName();//Set hostname value from jmx.xml file.
        } else { //Else
            hostName = NetworkUtils.getLocalHostname();
        }
        // Create an RMI connector and start it
        int rmiServerPort = jmxProperties.getRmiServerPort();
        if (rmiServerPort != -1) {
            jmxURL = "service:jmx:rmi://" + hostName + ":" + rmiServerPort + "/jndi/rmi://" + hostName + ":"
                    + rmiRegistryPort + "/jmxrmi";

        } else {
            jmxURL = "service:jmx:rmi:///jndi/rmi://" + hostName + ":" + rmiRegistryPort + "/jmxrmi";
        }
        JMXServiceURL url = new JMXServiceURL(jmxURL);

        // Security credentials are included in the env Map
        HashMap<String, CarbonJMXAuthenticator> env = new HashMap<String, CarbonJMXAuthenticator>();
        env.put(JMXConnectorServer.AUTHENTICATOR, new CarbonJMXAuthenticator());
        jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
        jmxConnectorServer.start();
        log.info("JMX Service URL  : " + jmxURL);
    } catch (Exception e) {
        String msg = "Could not initialize RMI server";
        log.error(msg, e);
    }
}

From source file:org.mule.management.agents.JmxAgent.java

public void initialise() throws InitialisationException {
    if (initialized) {
        return;//from   w  ww  .  ja  v  a2  s . c  o  m
    }
    if (!locateServer && !createServer) {
        throw new InitialisationException(new Message(Messages.JMX_CREATE_OR_LOCATE_SHOULD_BE_SET), this);
    }
    if (mBeanServer == null && locateServer) {
        List l = MBeanServerFactory.findMBeanServer(null);
        if (l != null && l.size() > 0) {
            mBeanServer = (MBeanServer) l.get(0);
        }
    }
    if (mBeanServer == null && createServer) {
        mBeanServer = MBeanServerFactory.createMBeanServer();
        serverCreated = true;
    }
    if (mBeanServer == null) {
        throw new InitialisationException(new Message(Messages.JMX_CANT_LOCATE_CREATE_SERVER), this);
    }
    if (connectorServerUrl != null) {
        try {
            JMXServiceURL url = new JMXServiceURL(connectorServerUrl);

            if (!credentials.isEmpty()) {
                JMXAuthenticator jmxAuthenticator = new SimplePasswordJmxAuthenticator();
                ((SimplePasswordJmxAuthenticator) jmxAuthenticator).setCredentials(credentials);
                connectorServerProperties.put(JMXConnectorServer.AUTHENTICATOR, jmxAuthenticator);
            }

            connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, connectorServerProperties,
                    mBeanServer);
        } catch (Exception e) {
            throw new InitialisationException(new Message(Messages.FAILED_TO_CREATE_X, "Jmx Connector"), e,
                    this);
        }
    }

    // We need to register all the services once the server has initialised
    MuleManager.getInstance().registerListener(new ModelEventListener() {
        public void onEvent(UMOServerEvent event) {
            if (event.getAction() == ModelEvent.MODEL_STARTED) {
                try {
                    registerStatisticsService();
                    registerMuleService();
                    registerConfigurationService();
                    registerModelService();

                    registerComponentServices();
                    registerEndpointServices();
                    registerConnectorServices();
                } catch (Exception e) {
                    throw new MuleRuntimeException(new Message(Messages.X_FAILED_TO_INITIALISE, "MBeans"), e);
                }
            }
        }
    });
    initialized = true;
}

From source file:org.apache.cassandra.utils.JMXServerUtils.java

private static Map<String, Object> configureJmxAuthentication() {
    Map<String, Object> env = new HashMap<>();
    if (!Boolean.getBoolean("com.sun.management.jmxremote.authenticate"))
        return env;

    // If authentication is enabled, initialize the appropriate JMXAuthenticator
    // and stash it in the environment settings.
    // A JAAS configuration entry takes precedence. If one is supplied, use
    // Cassandra's own custom JMXAuthenticator implementation which delegates
    // auth to the LoginModules specified by the JAAS configuration entry.
    // If no JAAS entry is found, an instance of the JDK's own
    // JMXPluggableAuthenticator is created. In that case, the admin may have
    // set a location for the JMX password file which must be added to env
    // before creating the authenticator. If no password file has been
    // explicitly set, it's read from the default location
    // $JAVA_HOME/lib/management/jmxremote.password
    String configEntry = System.getProperty("cassandra.jmx.remote.login.config");
    if (configEntry != null) {
        env.put(JMXConnectorServer.AUTHENTICATOR, new AuthenticationProxy(configEntry));
    } else {/*  w  w w .j  a  v a 2 s.  c o m*/
        String passwordFile = System.getProperty("com.sun.management.jmxremote.password.file");
        if (passwordFile != null) {
            // stash the password file location where JMXPluggableAuthenticator expects it
            env.put("jmx.remote.x.password.file", passwordFile);
        }

        env.put(JMXConnectorServer.AUTHENTICATOR, new JMXPluggableAuthenticatorWrapper(env));
    }

    return env;
}

From source file:org.jcommon.com.util.jmx.RmiAdptor.java

public void setCserver(MBeanServer server) throws MalformedURLException, IOException {
    if (port == 0 || name == null || addr == null) {
        throw new NullPointerException("data not be ready");
    }//from  www.  j a  v a 2  s  . c  o m
    try {
        registry = LocateRegistry.createRegistry(port);
    } catch (RemoteException e) {

    }
    HashMap<String, Object> prop = new HashMap<String, Object>();
    if (CREDENTIALS != null) {
        authenticator = new JMXAuthenticator() {

            public Subject authenticate(Object credentials) {
                logger.info(credentials.getClass().getName() + " is trying connect...");
                if (credentials instanceof String) {
                    if (credentials.equals(CREDENTIALS)) {
                        return new Subject();
                    }
                } else if (credentials instanceof String[]) {
                    String[] copy = (String[]) credentials;
                    String username = copy.length > 0 ? copy[0] : null;
                    String passwd = copy.length > 1 ? copy[1] : null;
                    logger.info(username + " is trying connect...");
                    if (passwd.equals(CREDENTIALS) && username.equals(user)) {
                        return new Subject();
                    }
                }
                throw new SecurityException("not authicated");
            }
        };

        prop.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
    }
    String url = "service:jmx:rmi:///jndi/rmi://" + addr + ":" + port + "/" + name;
    this.cserver = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL(url), prop, server);
}

From source file:org.wso2.andes.server.management.JMXManagedObjectRegistry.java

public void start() throws IOException, ConfigurationException {

    CurrentActor.get().message(ManagementConsoleMessages.STARTUP());

    //check if system properties are set to use the JVM's out-of-the-box JMXAgent
    if (areOutOfTheBoxJMXOptionsSet()) {
        CurrentActor.get().message(ManagementConsoleMessages.READY(true));
        return;//from w  w  w.j a va 2s  . co  m
    }

    IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
    int port = appRegistry.getConfiguration().getJMXManagementPort();

    //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
    RMIClientSocketFactory csf;
    RMIServerSocketFactory ssf;

    //check ssl enabled option in config, default to true if option is not set
    boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled();

    if (sslEnabled) {
        //set the SSL related system properties used by the SSL RMI socket factories to the values
        //given in the configuration file, unless command line settings have already been specified
        String keyStorePath;

        if (System.getProperty("javax.net.ssl.keyStore") != null) {
            keyStorePath = System.getProperty("javax.net.ssl.keyStore");
        } else {
            keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
        }

        //check the keystore path value is valid
        if (keyStorePath == null) {
            throw new ConfigurationException("JMX management SSL keystore path not defined, "
                    + "unable to start SSL protected JMX ConnectorServer");
        } else {
            //ensure the system property is set
            System.setProperty("javax.net.ssl.keyStore", keyStorePath);

            //check the file is usable
            File ksf = new File(keyStorePath);

            if (!ksf.exists()) {
                throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf + "\n"
                        + "Check broker configuration, or see create-example-ssl-stores script"
                        + "in the bin/ directory if you need to generate an example store.");
            }
            if (!ksf.canRead()) {
                throw new FileNotFoundException(
                        "Cannot read JMX management SSL keystore file: " + ksf + ". Check permissions.");
            }

            CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(ksf.getAbsolutePath()));
        }

        //check the key store password is set
        if (System.getProperty("javax.net.ssl.keyStorePassword") == null) {

            if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null) {
                throw new ConfigurationException("JMX management SSL keystore password not defined, "
                        + "unable to start requested SSL protected JMX server");
            } else {
                System.setProperty("javax.net.ssl.keyStorePassword",
                        appRegistry.getConfiguration().getManagementKeyStorePassword());
            }
        }

        //create the SSL RMI socket factories
        csf = new SslRMIClientSocketFactory();
        ssf = new SslRMIServerSocketFactory();
    } else {
        //Do not specify any specific RMI socket factories, resulting in use of the defaults.
        csf = null;
        ssf = null;
    }

    //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
    RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
    rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager());
    HashMap<String, Object> env = new HashMap<String, Object>();
    env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);

    /*
     * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub. 
     * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
     * As a result, only binds made using the object reference will succeed, thus securing it from external change. 
     */
    System.setProperty("java.rmi.server.randomIDs", "true");
    if (_useCustomSocketFactory) {
        _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory());
    } else {
        _rmiRegistry = LocateRegistry.createRegistry(port, null, null);
    }

    CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", port));

    /*
     * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls 
     * to bind the ConnectorServer to the registry, which will now fail as for security we have
     * locked it from any RMI based modifications, including our own. Instead, we will manually bind 
     * the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
     * 
     * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
     * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's. 
     */
    final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port + PORT_EXPORT_OFFSET, csf, ssf,
            env);
    String localHost;
    try {
        localHost = InetAddress.getLocalHost().getHostName();
    } catch (UnknownHostException ex) {
        localHost = "127.0.0.1";
    }
    final String hostname = localHost;
    final JMXServiceURL externalUrl = new JMXServiceURL("service:jmx:rmi://" + hostname + ":"
            + (port + PORT_EXPORT_OFFSET) + "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi");

    final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port + PORT_EXPORT_OFFSET);
    _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer) {
        @Override
        public synchronized void start() throws IOException {
            try {
                //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent                        
                _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
            } catch (AlreadyBoundException abe) {
                //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means.

                //IOExceptions are the only checked type throwable by the method, wrap and rethrow
                IOException ioe = new IOException(abe.getMessage());
                ioe.initCause(abe);
                throw ioe;
            }

            //now do the normal tasks
            super.start();
        }

        @Override
        public synchronized void stop() throws IOException {
            try {
                if (_rmiRegistry != null) {
                    _rmiRegistry.unbind("jmxrmi");
                }
            } catch (NotBoundException nbe) {
                //ignore
            }

            //now do the normal tasks
            super.stop();
        }

        @Override
        public JMXServiceURL getAddress() {
            //must return our pre-crafted url that includes the full details, inc JNDI details
            return externalUrl;
        }

    };

    //Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
    MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
    _cs.setMBeanServerForwarder(mbsf);

    NotificationFilterSupport filter = new NotificationFilterSupport();
    filter.enableType(JMXConnectionNotification.OPENED);
    filter.enableType(JMXConnectionNotification.CLOSED);
    filter.enableType(JMXConnectionNotification.FAILED);
    // Get the handler that is used by the above MBInvocationHandler Proxy.
    // which is the MBeanInvocationHandlerImpl and so also a NotificationListener
    _cs.addNotificationListener((NotificationListener) Proxy.getInvocationHandler(mbsf), filter, null);

    _cs.start();

    String connectorServer = (sslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
    CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, port + PORT_EXPORT_OFFSET));

    CurrentActor.get().message(ManagementConsoleMessages.READY(false));
}

From source file:org.apache.synapse.JmxAdapter.java

/**
 * Creates an environment context map containing the configuration used to start the
 * server connector./*  w w w  .j  a va  2 s  . c  o m*/
 * 
 * @return an environment context map containing the configuration used to start the server 
 *         connector
 */
private Map<String, Object> createContextMap() {
    Map<String, Object> env = new HashMap<String, Object>();

    if (jmxInformation.isAuthenticate()) {

        if (jmxInformation.getRemotePasswordFile() != null) {
            env.put("jmx.remote.x.password.file", jmxInformation.getRemotePasswordFile());
        } else {
            SecretInformation secretInformation = jmxInformation.getSecretInformation();
            // Get the global secret resolver
            //TODO This should be properly implemented if JMX adapter is going to use out side synapse
            PasswordManager pwManager = PasswordManager.getInstance();
            if (pwManager.isInitialized()) {
                secretInformation.setGlobalSecretResolver(pwManager.getSecretResolver());
            }
            env.put(JMXConnectorServer.AUTHENTICATOR,
                    new JmxSecretAuthenticator(jmxInformation.getSecretInformation()));
        }

        if (jmxInformation.getRemoteAccessFile() != null) {
            env.put("jmx.remote.x.access.file", jmxInformation.getRemoteAccessFile());
        }
    } else {
        log.warn("Using unsecured JMX remote access!");
    }

    if (jmxInformation.isRemoteSSL()) {
        log.info("Activated SSL communication");
        env.put("jmx.remote.rmi.client.socket.factory", new SslRMIClientSocketFactory());
        env.put("jmx.remote.rmi.server.socket.factory", new SslRMIServerSocketFactory());
    }

    return env;
}

From source file:com.continuent.tungsten.common.jmx.JmxManager.java

/**
 * Starts the JMX connector for the server.
 *//*from   w w w .j a v  a  2 s. c o  m*/
protected void startJmxConnector() {
    String serviceAddress = null;
    try {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

        serviceAddress = generateServiceAddress(host, beanPort, registryPort, serviceName);
        JMXServiceURL address = new JMXServiceURL(serviceAddress);

        // --- Define security attributes ---
        HashMap<String, Object> env = new HashMap<String, Object>();

        // --- Authentication based on password and access files---
        if (authenticationInfo != null && authenticationInfo.isAuthenticationNeeded()) {

            if (authenticationInfo.isUseTungstenAuthenticationRealm())
                env.put(JMXConnectorServer.AUTHENTICATOR, new RealmJMXAuthenticator(authenticationInfo));
            else
                env.put("jmx.remote.x.password.file", authenticationInfo.getPasswordFileLocation());

            env.put("jmx.remote.x.access.file", authenticationInfo.getAccessFileLocation());
        }

        // --- SSL encryption ---
        if (authenticationInfo != null && authenticationInfo.isEncryptionNeeded()) {
            // Keystore
            System.setProperty("javax.net.ssl.keyStore", authenticationInfo.getKeystoreLocation());
            System.setProperty("javax.net.ssl.keyStorePassword", authenticationInfo.getKeystorePassword());
            /**
             * Configure SSL. Protocols and ciphers are set in
             * securityHelper.setSecurityProperties and used by
             * SslRMIClientSocketFactory
             */
            try {
                String[] protocolArray = authenticationInfo.getEnabledProtocols().toArray(new String[0]);
                String[] allowedCipherSuites = authenticationInfo.getEnabledCipherSuites()
                        .toArray(new String[0]);
                String[] cipherArray;

                if (protocolArray.length == 0)
                    protocolArray = null;
                if (allowedCipherSuites.length == 0)
                    cipherArray = null;
                else {
                    // Ensure we choose an allowed cipher suite.
                    cipherArray = authenticationInfo.getJvmEnabledCipherSuites().toArray(new String[0]);
                    if (cipherArray.length == 0) {
                        // We don't have any cipher suites in common. This
                        // is not good!
                        String message = "Unable to find approved ciphers in the supported cipher suites on this JVM";
                        StringBuffer sb = new StringBuffer(message).append("\n");
                        sb.append(String.format("JVM supported cipher suites: %s\n",
                                StringUtils.join(SecurityHelper.getJvmSupportedCiphers())));
                        sb.append(String.format("Approved cipher suites from security.properties: %s\n",
                                StringUtils.join(allowedCipherSuites)));
                        logger.error(sb.toString());
                        throw new RuntimeException(message);
                    }
                }

                logger.info("Setting allowed JMX server protocols: " + StringUtils.join(protocolArray, ","));
                logger.info("Setting allowed JMX server ciphers: " + StringUtils.join(cipherArray, ","));
                SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
                SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(cipherArray, protocolArray,
                        false);
                env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
                env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
            } catch (IllegalArgumentException ie) {
                logger.warn("Some of the protocols or ciphers are not supported. " + ie.getMessage());
                throw new RuntimeException(ie.getLocalizedMessage(), ie);
            }
        }

        env.put(RMIConnectorServer.JNDI_REBIND_ATTRIBUTE, "true");
        JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(address, env, mbs);
        connector.start();

        logger.info(MessageFormat.format("JMXConnector: security.properties={0}",
                (authenticationInfo != null) ? authenticationInfo.getParentPropertiesFileLocation()
                        : "No security.properties file found !..."));
        if (authenticationInfo != null)
            logger.info(authenticationInfo.toString());
        logger.info(String.format("JMXConnector started at address %s", serviceAddress));

        jmxConnectorServer = connector;
    } catch (Throwable e) {
        throw new ServerRuntimeException(
                MessageFormat.format("Unable to create RMI listener: {0} -> {1}", getServiceProps(), e), e);
    }
}

From source file:org.mule.module.management.agent.AbstractJmxAgent.java

public void start() throws MuleException {
    try {//from  w w  w  .j a v a 2 s.  c  om
        // TODO cleanup rmi registry creation too
        initRMI();
        if (connectorServerUrl == null) {
            return;
        }

        logger.info("Creating and starting JMX agent connector Server");
        JMXServiceURL url = new JMXServiceURL(connectorServerUrl);
        if (connectorServerProperties == null) {
            connectorServerProperties = new HashMap<String, Object>(DEFAULT_CONNECTOR_SERVER_PROPERTIES);
        }
        if (!credentials.isEmpty()) {
            connectorServerProperties.put(JMXConnectorServer.AUTHENTICATOR, this.getJmxAuthenticator());
        }
        connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, connectorServerProperties,
                mBeanServer);
        connectorServer.start();
    } catch (ExportException e) {
        throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
    } catch (Exception e) {
        throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
    }
}

From source file:org.apache.geode.management.internal.ManagementAgent.java

/**
 * 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
 *///w  w w.  ja  v a  2 s. c  om
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" : ""));
    }
    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<>();

    // 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) {
                throw new IOException(x.getMessage(), x);
            }
            super.start();
        }
    };

    if (securityService.isIntegratedSecurity()) {
        shiroAuthenticator = new JMXShiroAuthenticator(this.securityService);
        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(this.securityService);
        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) {
            // Rewire the mbs hierarchy to set accessController
            ReadOpFileAccessController controller = new ReadOpFileAccessController(accessFile);
            controller.setMBeanServer(mbs);
        }
    }

    jmxConnectorServer.start();
    if (logger.isDebugEnabled()) {
        logger.debug("Finished starting jmx manager agent.");
    }
}