- /*
- * @(#)RMIConnectorServer.java 1.61 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.management.remote.rmi;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.ObjectOutputStream;
- import java.net.MalformedURLException;
- import java.rmi.Remote;
- import java.rmi.server.RemoteObject;
- import java.rmi.server.RMIClientSocketFactory;
- import java.rmi.server.RMIServerSocketFactory;
- import java.util.Collections;
- import java.util.Hashtable;
- import java.util.Map;
- import java.util.HashMap;
- import java.util.Set;
- import java.util.HashSet;
-
- import javax.naming.InitialContext;
- import javax.naming.NamingException;
-
- import javax.management.MBeanRegistration;
- import javax.management.MBeanServer;
- import javax.management.ObjectName;
- import javax.management.InstanceNotFoundException;
-
- import javax.management.remote.JMXConnectionNotification;
- import javax.management.remote.JMXConnector;
- import javax.management.remote.JMXConnectorServer;
- import javax.management.remote.JMXServiceURL;
- import javax.management.remote.MBeanServerForwarder;
-
- import com.sun.jmx.remote.security.MBeanServerFileAccessController;
- import com.sun.jmx.remote.util.ClassLogger;
- import com.sun.jmx.remote.util.EnvHelp;
-
- /**
- * <p>A JMX API connector server that creates RMI-based connections
- * from remote clients. Usually, such connector servers are made
- * using {@link javax.management.remote.JMXConnectorServerFactory
- * JMXConnectorServerFactory}. However, specialized applications can
- * use this class directly, for example with an {@link RMIServerImpl}
- * object.</p>
- *
- * @since 1.5
- * @since.unbundled 1.0
- */
- public class RMIConnectorServer extends JMXConnectorServer {
- /**
- * <p>Name of the attribute that specifies whether the {@link
- * RMIServer} stub that represents an RMI connector server should
- * override an existing stub at the same address. The value
- * associated with this attribute, if any, should be a string that
- * is equal, ignoring case, to <code>"true"</code> or
- * <code>"false"</code>. The default value is false.</p>
- */
- public static final String JNDI_REBIND_ATTRIBUTE =
- "jmx.remote.jndi.rebind";
-
- /**
- * <p>Name of the attribute that specifies the {@link
- * RMIClientSocketFactory} for the RMI objects created in
- * conjunction with this connector. The value associated with this
- * attribute must be of type <code>RMIClientSocketFactory</code> and can
- * only be specified in the <code>Map</code> argument supplied when
- * creating a connector server.</p>
- */
- public static final String RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE =
- "jmx.remote.rmi.client.socket.factory";
-
- /**
- * <p>Name of the attribute that specifies the {@link
- * RMIServerSocketFactory} for the RMI objects created in
- * conjunction with this connector. The value associated with this
- * attribute must be of type <code>RMIServerSocketFactory</code> and can
- * only be specified in the <code>Map</code> argument supplied when
- * creating a connector server.</p>
- */
- public static final String RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE =
- "jmx.remote.rmi.server.socket.factory";
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code>.
- * This is equivalent to calling {@link #RMIConnectorServer(
- * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
- * RMIConnectorServer(directoryURL,environment,null,null)}</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" and "jrmp"
- * are valid when this constructor is used.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment)
- throws IOException {
- this(url, environment, (MBeanServer) null);
- }
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
- * server.
- * This is equivalent to calling {@link #RMIConnectorServer(
- * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
- * RMIConnectorServer(directoryURL,environment,null,mbeanServer)}</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @param mbeanServer the MBean server to which the new connector
- * server is attached, or null if it will be attached by being
- * registered as an MBean in the MBean server.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" and "jrmp"
- * are valid when this constructor is used.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
- MBeanServer mbeanServer)
- throws IOException {
- this(url, environment, (RMIServerImpl) null, mbeanServer);
- }
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
- * server.</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @param rmiServerImpl An implementation of the RMIServer interface,
- * consistent with the protocol type specified in <var>url</var>.
- * If this parameter is non null, the protocol type specified by
- * <var>url</var> is not constrained, and is assumed to be valid.
- * Otherwise, only "rmi" and "iiop" will be recognized.
- *
- * @param mbeanServer the MBean server to which the new connector
- * server is attached, or null if it will be attached by being
- * registered as an MBean in the MBean server.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" and "jrmp"
- * are recognized when <var>rmiServerImpl</var> is null.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- *
- * @see #start
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
- RMIServerImpl rmiServerImpl,
- MBeanServer mbeanServer)
- throws IOException {
- super(mbeanServer);
-
- if (url == null) throw new
- IllegalArgumentException("Null JMXServiceURL");
- if (rmiServerImpl == null) {
- final String prt = url.getProtocol();
- if (prt == null || !(prt.equals("rmi") || prt.equals("iiop"))) {
- final String msg = "Invalid protocol type: " + prt;
- throw new MalformedURLException(msg);
- }
- final String urlPath = url.getURLPath();
- if (!urlPath.equals("")
- && !urlPath.equals("/")
- && !urlPath.startsWith("/jndi/")) {
- final String msg = "URL path must be empty or start with " +
- "/jndi/";
- throw new MalformedURLException(msg);
- }
- }
-
- if (environment == null)
- this.attributes = Collections.EMPTY_MAP;
- else {
- EnvHelp.checkAttributes(environment);
- this.attributes = Collections.unmodifiableMap(environment);
- }
-
- this.address = url;
- this.rmiServerImpl = rmiServerImpl;
- }
-
- /**
- * <p>Returns a client stub for this connector server. A client
- * stub is a serializable object whose {@link
- * JMXConnector#connect(Map) connect} method can be used to make
- * one new connection to this connector server.</p>
- *
- * @param env client connection parameters of the same sort that
- * could be provided to {@link JMXConnector#connect(Map)
- * JMXConnector.connect(Map)}. Can be null, which is equivalent
- * to an empty map.
- *
- * @return a client stub that can be used to make a new connection
- * to this connector server.
- *
- * @exception UnsupportedOperationException if this connector
- * server does not support the generation of client stubs.
- *
- * @exception IllegalStateException if the JMXConnectorServer is
- * not started (see {@link #isActive()}).
- *
- * @exception IOException if a communications problem means that a
- * stub cannot be created.
- **/
- public JMXConnector toJMXConnector(Map<String,?> env) throws IOException {
- // The serialized for of rmiServerImpl is automagically
- // a RMI server stub.
- if (!isActive()) throw new
- IllegalStateException("Connector is not active");
-
- // Merge maps
- Map usemap = new
- HashMap((this.attributes==null)?Collections.EMPTY_MAP:
- this.attributes);
-
- if (env != null) {
- EnvHelp.checkAttributes(env);
- usemap.putAll(env);
- }
-
- usemap = EnvHelp.filterAttributes(usemap);
-
- final RMIServer stub=(RMIServer)rmiServerImpl.toStub();
-
- return new RMIConnector(stub, usemap);
- }
-
- /**
- * <p>Activates the connector server, that is starts listening for
- * client connections. Calling this method when the connector
- * server is already active has no effect. Calling this method
- * when the connector server has been stopped will generate an
- * <code>IOException</code>.</p>
- *
- * <p>The behaviour of this method when called for the first time
- * depends on the parameters that were supplied at construction,
- * as described below.</p>
- *
- * <p>First, an object of a subclass of {@link RMIServerImpl} is
- * required, to export the connector server through RMI:</p>
- *
- * <ul>
- *
- * <li>If an <code>RMIServerImpl</code> was supplied to the
- * constructor, it is used.
- *
- * <li>Otherwise, if the protocol part of the
- * <code>JMXServiceURL</code> supplied to the constructor was
- * <code>iiop</code>, an object of type {@link RMIIIOPServerImpl}
- * is created.
- *
- * <li>Otherwise, if the <code>JMXServiceURL</code>
- * was null, or its protocol part was <code>rmi</code>, an object
- * of type {@link RMIJRMPServerImpl} is created.
- *
- * <li>Otherwise, the implementation can create an
- * implementation-specific {@link RMIServerImpl} or it can throw
- * {@link MalformedURLException}.
- *
- * </ul>
- *
- * <p>If the given address includes a JNDI directory URL as
- * specified in the package documentation for {@link
- * javax.management.remote.rmi}, then this
- * <code>RMIConnectorServer</code> will bootstrap by binding the
- * <code>RMIServerImpl</code> to the given address.</p>
- *
- * <p>If the URL path part of the <code>JMXServiceURL</code> was
- * empty or a single slash (<code>/</code>), then the RMI object
- * will not be bound to a directory. Instead, a reference to it
- * will be encoded in the URL path of the RMIConnectorServer
- * address (returned by {@link #getAddress()}). The encodings for
- * <code>rmi</code> and <code>iiop</code> are described in the
- * package documentation for {@link
- * javax.management.remote.rmi}.</p>
- *
- * <p>The behavior when the URL path is neither empty nor a JNDI
- * directory URL, or when the protocol is neither <code>rmi</code>
- * nor <code>iiop</code>, is implementation defined, and may
- * include throwing {@link MalformedURLException} when the
- * connector server is created or when it is started.</p>
- *
- * @exception IllegalStateException if the connector server has
- * not been attached to an MBean server.
- * @exception IOException if the connector server cannot be
- * started.
- */
- public synchronized void start() throws IOException {
- final boolean tracing = logger.traceOn();
-
- if (state == STARTED) {
- if (tracing) logger.trace("start", "already started");
- return;
- } else if (state == STOPPED) {
- if (tracing) logger.trace("start", "already stopped");
- throw new IOException("The server has been stopped.");
- }
-
- MBeanServer mbs = getMBeanServer();
- if (mbs == null)
- throw new IllegalStateException("This connector server is not " +
- "attached to an MBean server");
-
- // Check the internal access file property to see
- // if an MBeanServerForwarder is to be provided
- //
- if (attributes != null) {
- // Check if access file property is specified
- //
- String accessFile =
- (String) attributes.get("jmx.remote.x.access.file");
- if (accessFile != null) {
- // Access file property specified, create an instance
- // of the MBeanServerFileAccessController class
- //
- MBeanServerForwarder mbsf = null;
- try {
- mbsf = new MBeanServerFileAccessController(accessFile);
- } catch (IOException e) {
- throw (IllegalArgumentException)
- EnvHelp.initCause(
- new IllegalArgumentException(e.getMessage()), e);
- }
- // Set the MBeanServerForwarder
- //
- setMBeanServerForwarder(mbsf);
- mbs = getMBeanServer();
- }
- }
-
- try {
- if (tracing) logger.trace("start", "setting default class loader");
- defaultClassLoader = EnvHelp.resolveServerClassLoader(attributes, mbs);
- } catch (InstanceNotFoundException infc) {
- IllegalArgumentException x = new
- IllegalArgumentException("ClassLoader not found: "+infc);
- throw (IllegalArgumentException)EnvHelp.initCause(x,infc);
- }
-
- if (tracing) logger.trace("start", "setting RMIServer object");
- final RMIServerImpl rmiServer;
-
- if (rmiServerImpl != null)
- rmiServer = rmiServerImpl;
- else
- rmiServer = newServer();
-
- rmiServer.setMBeanServer(mbs);
- rmiServer.setDefaultClassLoader(defaultClassLoader);
- rmiServer.setRMIConnectorServer(this);
- rmiServer.export();
-
- try {
- if (tracing) logger.trace("start", "getting RMIServer object to export");
- final RMIServer objref = objectToBind(rmiServer, attributes);
-
- if (address != null && address.getURLPath().startsWith("/jndi/")) {
- final String jndiUrl = address.getURLPath().substring(6);
-
- if (tracing)
- logger.trace("start", "Using external directory: " + jndiUrl);
-
- final boolean rebind;
-
- String rebindS = (String)
- attributes.get(JNDI_REBIND_ATTRIBUTE);
- if (rebindS == null) rebind = false;
- else if (rebindS.equalsIgnoreCase("true")) rebind = true;
- else if (rebindS.equalsIgnoreCase("false")) rebind = false;
- else throw new
- IllegalArgumentException(JNDI_REBIND_ATTRIBUTE + "must" +
- " be \"true\" or \"false\"");
-
- if (tracing)
- logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);
-
- try {
- if (tracing) logger.trace("start", "binding to " + jndiUrl);
-
- final Hashtable usemap = EnvHelp.mapToHashtable(attributes);
- final boolean isIiop = isIiopURL(address, true);
- if (isIiop) {
- // Make sure java.naming.corba.orb is in the Map.
- usemap.put(EnvHelp.DEFAULT_ORB,
- RMIConnector.resolveOrb(attributes));
- }
-
- bind(jndiUrl, usemap, objref, rebind);
- boundJndiUrl = jndiUrl;
- } catch (NamingException e) {
- // fit e in the nested exception if we are on 1.4
- throw newIOException("Cannot bind to URL ["+jndiUrl+"]: "
- + e, e);
- }
- } else {
- // if jndiURL is null, we must encode the stub into the URL.
- if (tracing) logger.trace("start", "Encoding URL");
-
- encodeStubInAddress(objref, attributes);
-
- if (tracing) logger.trace("start", "Encoded URL: " + this.address);
- }
- } catch (Exception e) {
- try {
- rmiServer.close();
- } catch (Exception x) {
- // OK: we are already throwing another exception
- }
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- else if (e instanceof IOException)
- throw (IOException) e;
- else
- throw newIOException("Got unexpected exception while " +
- "starting the connector server: "
- + e, e);
- }
-
- rmiServerImpl = rmiServer;
-
- synchronized(openedServers) {
- openedServers.add(this);
- }
-
- state = STARTED;
-
- if (tracing) {
- logger.trace("start", "Connector Server Address = " + address);
- logger.trace("start", "started.");
- }
- }
-
- /**
- * <p>Deactivates the connector server, that is, stops listening for
- * client connections. Calling this method will also close all
- * client connections that were made by this server. After this
- * method returns, whether normally or with an exception, the
- * connector server will not create any new client
- * connections.</p>
- *
- * <p>Once a connector server has been stopped, it cannot be started
- * again.</p>
- *
- * <p>Calling this method when the connector server has already
- * been stopped has no effect. Calling this method when the
- * connector server has not yet been started will disable the
- * connector server object permanently.</p>
- *
- * <p>If closing a client connection produces an exception, that
- * exception is not thrown from this method. A {@link
- * JMXConnectionNotification} is emitted from this MBean with the
- * connection ID of the connection that could not be closed.</p>
- *
- * <p>Closing a connector server is a potentially slow operation.
- * For example, if a client machine with an open connection has
- * crashed, the close operation might have to wait for a network
- * protocol timeout. Callers that do not want to block in a close
- * operation should do it in a separate thread.</p>
- *
- * <p>This method calls the method {@link RMIServerImpl#close()
- * close} on the connector server's <code>RMIServerImpl</code>
- * object.</p>
- *
- * <p>If the <code>RMIServerImpl</code> was bound to a JNDI
- * directory by the {@link #start() start} method, it is unbound
- * from the directory by this method.</p>
- *
- * @exception IOException if the server cannot be closed cleanly,
- * or if the <code>RMIServerImpl</code> cannot be unbound from the
- * directory. When this exception is thrown, the server has
- * already attempted to close all client connections, if
- * appropriate; to call {@link RMIServerImpl#close()}; and to
- * unbind the <code>RMIServerImpl</code> from its directory, if
- * appropriate. All client connections are closed except possibly
- * those that generated exceptions when the server attempted to
- * close them.
- */
- public void stop() throws IOException {
- final boolean tracing = logger.traceOn();
-
- synchronized (this) {
- if (state == STOPPED) {
- if (tracing) logger.trace("stop","already stopped.");
- return;
- } else if (state == CREATED) {
- if (tracing) logger.trace("stop","not started yet.");
- }
-
- if (tracing) logger.trace("stop", "stopping.");
- state = STOPPED;
- }
-
- synchronized(openedServers) {
- openedServers.remove(this);
- }
-
- IOException exception = null;
-
- // rmiServerImpl can be null if stop() called without start()
- if (rmiServerImpl != null) {
- try {
- if (tracing) logger.trace("stop", "closing RMI server.");
- rmiServerImpl.close();
- } catch (IOException e) {
- if (tracing) logger.trace("stop", "failed to close RMI server: " + e);
- if (logger.debugOn()) logger.debug("stop",e);
- exception = e;
- }
- }
-
- if (boundJndiUrl != null) {
- try {
- if (tracing)
- logger.trace("stop",
- "unbind from external directory: " + boundJndiUrl);
-
- final Hashtable usemap = EnvHelp.mapToHashtable(attributes);
- final boolean isIiop = isIiopURL(address, true);
- if (isIiop) {
- // Make sure java.naming.corba.orb is in the Map.
- usemap.put(EnvHelp.DEFAULT_ORB,
- RMIConnector.resolveOrb(attributes));
- }
- InitialContext ctx =
- new InitialContext(usemap);
- ctx.unbind(boundJndiUrl);
- ctx.close();
- } catch (NamingException e) {
- if (tracing) logger.trace("stop", "failed to unbind RMI server: "+e);
- if (logger.debugOn()) logger.debug("stop",e);
- // fit e in as the nested exception if we are on 1.4
- if (exception == null)
- exception = newIOException("Cannot bind to URL: " + e, e);
- }
- }
-
- if (exception != null) throw exception;
-
- if (tracing) logger.trace("stop", "stopped");
- }
-
- public synchronized boolean isActive() {
- return (state == STARTED);
- }
-
- public JMXServiceURL getAddress() {
- if (!isActive())
- return null;
- return address;
- }
-
- public Map<String,?> getAttributes() {
- Map map = EnvHelp.filterAttributes(attributes);
- return Collections.unmodifiableMap(map);
- }
-
- /* We repeat the definitions of connection{Opened,Closed,Failed}
- here so that they are accessible to other classes in this package
- even though they have protected access. */
-
- protected void connectionOpened(String connectionId, String message,
- Object userData) {
- super.connectionOpened(connectionId, message, userData);
- }
-
- protected void connectionClosed(String connectionId, String message,
- Object userData) {
- super.connectionClosed(connectionId, message, userData);
- }
-
- protected void connectionFailed(String connectionId, String message,
- Object userData) {
- super.connectionFailed(connectionId, message, userData);
- }
-
- /**
- * Bind a stub to a registry.
- * @param jndiUrl URL of the stub in the registry, extracted
- * from the <code>JMXServiceURL</code>.
- * @param attributes A Hashtable containing environment parameters,
- * built from the Map specified at this object creation.
- * @param rmiServer The object to bind in the registry
- * @param rebind true if the object must be rebound.
- **/
- void bind(String jndiUrl, Hashtable attributes,
- RMIServer rmiServer, boolean rebind)
- throws NamingException, MalformedURLException {
- // if jndiURL is not null, we nust bind the stub to a
- // directory.
- InitialContext ctx =
- new InitialContext(attributes);
-
- if (rebind)
- ctx.rebind(jndiUrl, rmiServer);
- else
- ctx.bind(jndiUrl, rmiServer);
- ctx.close();
- }
-
- /**
- * Creates a new RMIServerImpl.
- **/
- RMIServerImpl newServer() throws IOException {
- final boolean iiop = isIiopURL(address,true);
- final int port;
- if (address == null)
- port = 0;
- else
- port = address.getPort();
- if (iiop)
- return newIIOPServer(attributes);
- else
- return newJRMPServer(attributes, port);
- }
-
- /**
- * Encode a stub into the JMXServiceURL.
- * @param rmiServer The stub object to encode in the URL
- * @param attributes A Map containing environment parameters,
- * built from the Map specified at this object creation.
- **/
- private void encodeStubInAddress(RMIServer rmiServer, Map attributes)
- throws IOException {
-
- final String protocol, host;
- final int port;
-
- if (address == null) {
- if (rmiServer instanceof javax.rmi.CORBA.Stub)
- protocol = "iiop";
- else
- protocol = "rmi";
- host = null; // will default to local host name
- port = 0;
- } else {
- protocol = address.getProtocol();
- host = (address.getHost().equals("")) ? null : address.getHost();
- port = address.getPort();
- }
-
- final String urlPath = encodeStub(rmiServer, attributes);
-
- address = new JMXServiceURL(protocol, host, port, urlPath);
- }
-
- static boolean isIiopURL(JMXServiceURL directoryURL, boolean strict)
- throws MalformedURLException {
- String protocol = directoryURL.getProtocol();
- if (protocol.equals("rmi"))
- return false;
- else if (protocol.equals("iiop"))
- return true;
- else if (strict) {
-
- throw new MalformedURLException("URL must have protocol " +
- "\"rmi\" or \"iiop\": \"" +
- protocol + "\"");
- }
- return false;
- }
-
- /**
- * Returns the IOR of the given rmiServer.
- **/
- static String encodeStub(RMIServer rmiServer, Map env) throws IOException {
- if (rmiServer instanceof javax.rmi.CORBA.Stub)
- return "/ior/" + encodeIIOPStub(rmiServer, env);
- else
- return "/stub/" + encodeJRMPStub(rmiServer, env);
- }
-
- static String encodeJRMPStub(RMIServer rmiServer, Map env)
- throws IOException {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(rmiServer);
- oout.close();
- byte[] bytes = bout.toByteArray();
- return byteArrayToBase64(bytes);
- }
-
- static String encodeIIOPStub(RMIServer rmiServer, Map env)
- throws IOException {
- try {
- javax.rmi.CORBA.Stub stub =
- (javax.rmi.CORBA.Stub) rmiServer;
- return stub._orb().object_to_string(stub);
- } catch (org.omg.CORBA.BAD_OPERATION x) {
- throw newIOException(x.getMessage(), x);
- }
- }
-
- /**
- * Object that we will bind to the registry.
- * This object is a stub connected to our RMIServerImpl.
- **/
- private static RMIServer objectToBind(RMIServerImpl rmiServer, Map env)
- throws IOException {
- return RMIConnector.
- connectStub((RMIServer)rmiServer.toStub(),env);
- }
-
- private static RMIServerImpl newJRMPServer(Map env, int port)
- throws IOException {
- RMIClientSocketFactory csf = (RMIClientSocketFactory)
- env.get(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
- RMIServerSocketFactory ssf = (RMIServerSocketFactory)
- env.get(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
- return new RMIJRMPServerImpl(port, csf, ssf, env);
- }
-
- private static RMIServerImpl newIIOPServer(Map env)
- throws IOException {
- return new RMIIIOPServerImpl(env);
- }
-
- private static String byteArrayToBase64(byte[] a) {
- int aLen = a.length;
- int numFullGroups = aLen3;
- int numBytesInPartialGroup = aLen - 3*numFullGroups;
- int resultLen = 4*((aLen + 2)/3);
- StringBuffer result = new StringBuffer(resultLen);
-
- // Translate all full groups from byte array elements to Base64
- int inCursor = 0;
- for (int i=0; i<numFullGroups; i++) {
- int byte0 = a[inCursor++] & 0xff;
- int byte1 = a[inCursor++] & 0xff;
- int byte2 = a[inCursor++] & 0xff;
- result.append(intToAlpha[byte0 >> 2]);
- result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
- result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
- result.append(intToAlpha[byte2 & 0x3f]);
- }
-
- // Translate partial group if present
- if (numBytesInPartialGroup != 0) {
- int byte0 = a[inCursor++] & 0xff;
- result.append(intToAlpha[byte0 >> 2]);
- if (numBytesInPartialGroup == 1) {
- result.append(intToAlpha[(byte0 << 4) & 0x3f]);
- result.append("==");
- } else {
- // assert numBytesInPartialGroup == 2;
- int byte1 = a[inCursor++] & 0xff;
- result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
- result.append(intToAlpha[(byte1 << 2)&0x3f]);
- result.append('=');
- }
- }
- // assert inCursor == a.length;
- // assert result.length() == resultLen;
- return result.toString();
- }
-
- /**
- * This array is a lookup table that translates 6-bit positive integer
- * index values into their "Base64 Alphabet" equivalents as specified
- * in Table 1 of RFC 2045.
- */
- private static final char intToAlpha[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
- };
-
- /**
- * Construct a new IOException with a nested exception.
- * The nested exception is set only if JDK >= 1.4
- */
- private static IOException newIOException(String message,
- Throwable cause) {
- final IOException x = new IOException(message);
- return (IOException)EnvHelp.initCause(x,cause);
- }
-
-
- // Private variables
- // -----------------
-
- private static ClassLogger logger =
- new ClassLogger("javax.management.remote.rmi", "RMIConnectorServer");
-
- private JMXServiceURL address;
- private RMIServerImpl rmiServerImpl;
- private final Map attributes;
- private ClassLoader defaultClassLoader = null;
-
- private String boundJndiUrl;
-
- // state
- private static final int CREATED = 0;
- private static final int STARTED = 1;
- private static final int STOPPED = 2;
-
- private int state = CREATED;
- private final static Set openedServers = new HashSet();
- }