FileDocCategorySizeDatePackage
JmxConnectorServerDriver.javaAPI DocGlassfish v2 API15772Wed Aug 01 11:38:18 BST 2007com.sun.enterprise.admin.jmx.remote.server.rmi

JmxConnectorServerDriver

public class JmxConnectorServerDriver extends Object
A Class to initialize the JMX Connector Servers in the system. It has its own configuration that determines the characteristics of the connector server end that will be started. It is important to note the various configurable parameters provided by this class. Implementation Note: This class is not thread safe. Callers have to take care of serialization of calls when necessary.
author
kedar
since
Sun Java System Application Server 8.1

Fields Summary
private static com.sun.enterprise.admin.jmx.remote.IStringManager
sm
private final Map
env
private JMXServiceURL
url
private JMXServiceURL
jconsoleurl
private int
port
private String
bindAddress
private com.sun.enterprise.admin.jmx.remote.server.rmi.RemoteJmxProtocol
protocol
private boolean
secureRegistry
private boolean
ssl
private RMIServerSocketFactory
rmissf
private RMIClientSocketFactory
rmicsf
private boolean
auth
private JMXAuthenticator
authenticator
private Logger
logger
private MBeanServer
mbs
Constructors Summary
public JmxConnectorServerDriver()
Creates a JMXConnectorServerDriver instance with default values for the various parameters. The protocol defaults to "rmi/jrmp". The rmi registry is not secure by default. An available port is selected. The authentication is turned off by default.

    
                                                  
    
      
        this.env = new HashMap();
        this.protocol = RemoteJmxProtocol.RMIJRMP;
        this.secureRegistry = false;
        this.port = getFreePort();
        this.ssl = false;
        this.auth = false;
        this.authenticator = null;
        logger = Logger.getLogger(this.getClass().getName());
    
Methods Summary
private voidcreateEnvironment()

        env.clear();
        handleSsl();        
        handleAuth();
    
private voidformJmxServiceUrl()

        //Note that the Connector Server can only be 
        //started on the host where this method is called
        if (protocol == RemoteJmxProtocol.RMIJRMP) {
            this.url = JmxServiceUrlFactory.forRmiWithJndiInAppserver(
                JmxServiceUrlFactory.localhost(), this.port);
            this.jconsoleurl = JmxServiceUrlFactory.forJconsoleOverRmiWithJndiInAppserver(
                JmxServiceUrlFactory.localhost(), this.port);
        }
    
public static intgetFreePort()
Gets a free port at the time of call to this method. The logic leverages the built in java.net.ServerSocket implementation which binds a server socket to a free port when instantiated with a port 0 .

Note that this method guarantees the availability of the port only at the time of call. The method does not bind to this port.

Checking for free port can fail for several reasons which may indicate potential problems with the system. This method acknowledges the fact and following is the general contract:

  • Best effort is made to find a port which can be bound to. All the exceptional conditions in the due course are considered SEVERE.
  • If any exceptional condition is experienced, 0 is returned, indicating that the method failed for some reasons and the callers should take the corrective action. (The method need not always throw an exception for this).
  • Method is synchronized on this class.

    return
    integer depicting the free port number available at this time 0 otherwise.

            int                             freePort        = 0;
            boolean                         portFound       = false;
            ServerSocket                    serverSocket    = null;
    
            synchronized (JmxConnectorServerDriver.class) {
                try {
                    /*following call normally returns the free port,
                      to which the ServerSocket is bound. */
                    serverSocket = new ServerSocket(0);
                    freePort = serverSocket.getLocalPort();
                    portFound = true;
                } catch(Exception e) {
                    //squelch the exception
                } finally {
                    if (!portFound) freePort = 0;
                    try {
                        if (serverSocket != null) {
                            serverSocket.close();
                            if (! serverSocket.isClosed())
                                throw new Exception("local exception ...");
                        }
                    } catch(Exception e) {
                        //squelch the exception
                        freePort = 0;
                    }
                }
                return freePort;
            }
        
  • private voidhandleAuth()

            if (protocol == RemoteJmxProtocol.RMIJRMP || 
                protocol == RemoteJmxProtocol.RMIIIOP) {
                if (auth) {
                    if (authenticator == null) {
                        String msg = "Internal: The authentication is on, but the authenticator is null";
                        throw new IllegalArgumentException("msg");
                    }
                    env.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
                }
            }
        
    private voidhandleSsl()

            if (protocol == RemoteJmxProtocol.RMIJRMP)
                env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmissf);
            if (ssl) env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, rmicsf);
        
    private voidlogJconsoleStartup(javax.management.remote.JMXConnectorServer cs)

            logger.log(Level.INFO, "rjmx.std.address", cs.getAddress().toString());
            logger.log(Level.INFO, "rjmx.std.status", "" + cs.isActive());
        
    private voidlogStartup(javax.management.remote.JMXConnectorServer cs)

            logger.log(Level.FINE, "rjmx.lc.address", cs.getAddress().toString());
            logger.log(Level.FINE, "rjmx.lc.status", "" + cs.isActive());
        
    private voidprepare()

            if (protocol == RemoteJmxProtocol.RMIJRMP) {
                RMIServerSocketFactory rmiregssf = new RMIServerSocketFactory() {
                    public ServerSocket createServerSocket(int port)
                                    throws IOException {
                        return new ServerSocket(
                            port, 0, InetAddress.getByName(bindAddress));
                    }
                };
                new RmiStubRegistryHandler(port, secureRegistry, logger, rmiregssf);
            }
        
    public voidsetAuthentication(boolean auth)
    Sets Authentication value. If true, then every connection establishment should be authenticated. This is generally done by implementation of JMXAuthenticator interface.

            this.auth = auth;
        
    public voidsetAuthenticator(javax.management.remote.JMXAuthenticator authenticator)
    Sets the Authenticator Object. This Object is responsible for authenticating the connection.

            //TODO
            //if (authenticator == null)
                //throw new IllegalArgumentException ("null authenticator");
            this.authenticator = authenticator;
        
    public voidsetBindAddress(java.lang.String bindAddress)
    Sets the bindAddress for the inprocess rmi registry to the given value.

            this.bindAddress = bindAddress;
        
    public voidsetLogger(java.util.logging.Logger logger)
    Sets the Logger

            if (logger == null)
                throw new IllegalArgumentException("Internal: null logger");
            this.logger = logger;
        
    public voidsetMBeanServer(javax.management.MBeanServer mbs)
    Sets the MBeanServer that will be associated with the created Connector Server. May not be null.

    throws
    IllegalArgumentException in case the argument is null.

            if (mbs == null)
                throw new IllegalArgumentException ("null mbs");
            this.mbs = mbs;
        
    public voidsetPort(int port)
    Sets the port to the given value. Note that NO checks whatsoever made for the validity of port

            // not going to check for port validity
            this.port = port;
        
    public voidsetProtocol(com.sun.enterprise.admin.jmx.remote.server.rmi.RemoteJmxProtocol protocol)
    Sets the protocol to one of the values in RemoteJmxProtocol.

    see
    RemoteJmxProtocol

            this.protocol = protocol;
        
    public voidsetRmiClientSocketFactory(java.rmi.server.RMIClientSocketFactory f)
    Sets the RMIClientSocketFactory. This is the custom client socket factory that RMI Connector Server would use. Really useful only if ssl is set to true by using setSsl(true). If ssl is false, this value is not passed on to the environmental map of connector server. If ssl is true this value can not be null.

            if (ssl && f == null)
                throw new IllegalArgumentException("Internal: null client socket factory passed with ssl ON");
            this.rmicsf = f;
        
    public voidsetRmiRegistrySecureFlag(boolean secure)
    Sets if the rmi registry is secure.

            this.secureRegistry = secure;
        
    public voidsetRmiServerSocketFactory(java.rmi.server.RMIServerSocketFactory f)
    Sets the RMIServerSocketFactory. This is the custom server socket factory that RMI Connector Server would use. Really useful only if ssl is set to true by using setSsl(true). If ssl is false, this value is not passed on to the environmental map of connector server. If ssl is true then this value can not be null.

            if (ssl && f == null)
                throw new IllegalArgumentException("Internal: null server socket factory passed with ssl ON");
            this.rmissf = f;
        
    public voidsetSsl(boolean ssl)
    Sets if Transport Layer Security is on. Additional configuration is needed when ssl is on.

            this.ssl = ssl;
        
    public javax.management.remote.JMXConnectorServerstartConnectorServer()
    Starts the configured ConnectorServer. Note that the same connector server is returned. Internally the naming service may be started if need be. In case of RMI Connector, as of June 2004 the rmi registry is started.

    throws
    IOException if the connector server could not be started.

            //using the jndi form everywhere as stub-form is not usable.
            prepare();
            formJmxServiceUrl();
            createEnvironment();
            
            final JMXConnectorServer cs = 
                JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
    
            cs.start();
            logStartup(cs);
            return ( cs );
        
    public javax.management.remote.JMXConnectorServerstartJconsoleConnectorServer()

            // This env is ditto with the System JMX Connector Server, except SSL ClientSocketFactory.
            final RMIClientSocketFactory cf = new SslRMIClientSocketFactory();
            final Map jconsoleenv = new HashMap(env);
            if (ssl) 
                jconsoleenv.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, cf);
            final JMXConnectorServer jconsolecs = 
                JMXConnectorServerFactory.newJMXConnectorServer(jconsoleurl, jconsoleenv, mbs);
            jconsolecs.start();
            logJconsoleStartup(jconsolecs);
            return ( jconsolecs );
        
    public voidstopConnectorServer(javax.management.remote.JMXConnectorServer cs)
    A wrapper to shutdown the passed connector server. This method, in that regard just behaves like a static method. Note that ref may not be null.

    param
    cs instance of JMXConnectorServer that needs to be stopped
    throws
    IOException in case the stopping process throws any exception

            final String cad = cs.getAddress().toString();
            if (cs.isActive()) {
                logger.log(Level.FINE, "rjmx.lc.stopping", cad);
                cs.stop();
            }
            else {
                final String msg = "JMX Connector Server: " + cad + " is not active";
                logger.fine(msg);
            }