FileDocCategorySizeDatePackage
RMIConnector.javaAPI DocJava SE 5 API87817Fri Aug 26 14:57:38 BST 2005javax.management.remote.rmi

RMIConnector

public class RMIConnector extends Object implements Serializable, JMXConnector

A connection to a remote RMI connector. Usually, such connections are made using {@link javax.management.remote.JMXConnectorFactory JMXConnectorFactory}. However, specialized applications can use this class directly, for example with an {@link RMIServer} stub obtained without going through JNDI.

since
1.5
since.unbundled
1.0

Fields Summary
private static final ClassLogger
logger
private static final long
serialVersionUID
private static final String
rmiConnectionImplStubClassName
private static final Class
rmiConnectionImplStubClass
private static final String
pRefClassName
private static final Constructor
proxyRefConstructor
private static final String
iiopConnectionStubClassName
private static final String
proxyStubClassName
private static final String
pInputStreamClassName
private static final Class
proxyStubClass
private static final byte[]
base64ToInt
This array is a lookup table that translates unicode characters drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 alphabet but fall within the bounds of the array are translated to -1.
private final RMIServer
rmiServer
private final JMXServiceURL
jmxServiceURL
private transient Map
env
private transient ClassLoader
defaultClassLoader
private transient RMIConnection
connection
private transient String
connectionId
private long
clientNotifID
private transient WeakHashMap
rmbscMap
private transient RMINotifClient
rmiNotifClient
private transient long
clientNotifCounter
private transient boolean
connected
private transient boolean
terminated
private transient int[]
terminationLock
private transient Exception
closeException
private transient NotificationBroadcasterSupport
connectionBroadcaster
private transient ClientCommunicatorAdmin
communicatorAdmin
private static WeakReference
orb
A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to connect unconnected stubs.
private static final ObjectName
delegateName
Constructors Summary
private RMIConnector(RMIServer rmiServer, JMXServiceURL address, Map environment)


        
                           
        if (rmiServer == null && address == null) throw new
          IllegalArgumentException("rmiServer and jmxServiceURL both null");

	initTransients();

	this.rmiServer = rmiServer;
        this.jmxServiceURL = address;
        if (environment == null) {
            this.env = Collections.EMPTY_MAP;
        } else {
            EnvHelp.checkAttributes(environment);
            this.env = Collections.unmodifiableMap(environment);
        }
    
public RMIConnector(JMXServiceURL url, Map environment)

Constructs an RMIConnector that will connect the RMI connector server with the given address.

The address can refer directly to the connector server, using one of the following syntaxes:

service:jmx:rmi://[host[:port]]/stub/encoded-stub
service:jmx:iiop://[host[:port]]/ior/encoded-IOR

(Here, the square brackets [] are not part of the address but indicate that the host and port are optional.)

The address can instead indicate where to find an RMI stub through JNDI, using one of the following syntaxes:

service:jmx:rmi://[host[:port]]/jndi/jndi-name
service:jmx:iiop://[host[:port]]/jndi/jndi-name

An implementation may also recognize additional address syntaxes, for example:

service:jmx:iiop://[host[:port]]/stub/encoded-stub

param
url the address of the RMI connector server.
param
environment additional attributes specifying how to make the connection. For JNDI-based addresses, these attributes can usefully include JNDI attributes recognized by {@link InitialContext#InitialContext(Hashtable) InitialContext}. This parameter can be null, which is equivalent to an empty Map.
exception
IllegalArgumentException if url is null.

        this(null, url, environment);
    
public RMIConnector(RMIServer rmiServer, Map environment)

Constructs an RMIConnector using the given RMI stub.

param
rmiServer an RMI stub representing the RMI connector server.
param
environment additional attributes specifying how to make the connection. This parameter can be null, which is equivalent to an empty Map.
exception
IllegalArgumentException if rmiServer is null.

        this(rmiServer, null, environment);
    
Methods Summary
public voidaddConnectionNotificationListener(javax.management.NotificationListener listener, javax.management.NotificationFilter filter, java.lang.Object handback)

	
	if (listener == null) 
	    throw new NullPointerException("listener");
	connectionBroadcaster.addNotificationListener(listener, filter,
						      handback);
    
private java.lang.IntegeraddListenerWithSubject(javax.management.ObjectName name, java.rmi.MarshalledObject filter, javax.security.auth.Subject delegationSubject, boolean reconnect)

	    
	final boolean debug = logger.debugOn();
	if (debug)
	    logger.debug("addListenerWithSubject",
			 "(ObjectName,MarshalledObject,Subject)");	

	final ClassLoader old = pushDefaultClassLoader();
	    
	final ObjectName[] names = new ObjectName[] {name};
	final MarshalledObject[] filters = new MarshalledObject[] {filter};
	final Subject[] delegationSubjects = new Subject[] {
	    delegationSubject
	};

	final Integer[] listenerIDs =
	    addListenersWithSubjects(names,filters,delegationSubjects,
					  reconnect);
	    
	if (debug) logger.debug("addListenerWithSubject","listenerID="
				+ listenerIDs[0]);
	return listenerIDs[0];
    
private java.lang.Integer[]addListenersWithSubjects(javax.management.ObjectName[] names, java.rmi.MarshalledObject[] filters, javax.security.auth.Subject[] delegationSubjects, boolean reconnect)


	final boolean debug = logger.debugOn();
	if (debug)
	logger.debug("addListenersWithSubjects",
			 "(ObjectName[],MarshalledObject[],Subject[])");

	final ClassLoader old = pushDefaultClassLoader();
	Integer[] listenerIDs = null;

	try {
	    listenerIDs = connection.addNotificationListeners(names,
							      filters,
							  delegationSubjects);
	} catch (NoSuchObjectException noe) {
	    // maybe reconnect
	    if (reconnect) {
		communicatorAdmin.gotIOException(noe);
		
		listenerIDs = connection.addNotificationListeners(names,
						       filters,
						       delegationSubjects);
	    } else {
		throw noe;
	    }
	} catch (IOException ioe) {
	    // send a failed notif if necessary
	    communicatorAdmin.gotIOException(ioe);
	} finally {
	    popDefaultClassLoader(old);
	}
	    
	if (debug) logger.debug("addListenersWithSubjects","registered "
				+ listenerIDs.length + " listener(s)");
	return listenerIDs;
    
private static byte[]base64ToByteArray(java.lang.String s)

        int sLen = s.length();
        int numGroups = sLen/4;
        if (4*numGroups != sLen)
            throw new IllegalArgumentException(
                "String length must be a multiple of four.");
        int missingBytesInLastGroup = 0;
        int numFullGroups = numGroups;
        if (sLen != 0) {
            if (s.charAt(sLen-1) == '=") {
                missingBytesInLastGroup++;
                numFullGroups--;
            }
            if (s.charAt(sLen-2) == '=")
                missingBytesInLastGroup++;
        }
        byte[] result = new byte[3*numGroups - missingBytesInLastGroup];

        // Translate all full groups from base64 to byte array elements
        int inCursor = 0, outCursor = 0;
        for (int i=0; i<numFullGroups; i++) {
            int ch0 = base64toInt(s.charAt(inCursor++));
            int ch1 = base64toInt(s.charAt(inCursor++));
            int ch2 = base64toInt(s.charAt(inCursor++));
            int ch3 = base64toInt(s.charAt(inCursor++));
            result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
            result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
            result[outCursor++] = (byte) ((ch2 << 6) | ch3);
        }

        // Translate partial group, if present
        if (missingBytesInLastGroup != 0) {
            int ch0 = base64toInt(s.charAt(inCursor++));
            int ch1 = base64toInt(s.charAt(inCursor++));
            result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));

            if (missingBytesInLastGroup == 1) {
                int ch2 = base64toInt(s.charAt(inCursor++));
                result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
            }
        }
        // assert inCursor == s.length()-missingBytesInLastGroup;
        // assert outCursor == result.length;
        return result;
    
private static intbase64toInt(char c)
Translates the specified character, which is assumed to be in the "Base 64 Alphabet" into its equivalent 6-bit positive integer.

throw
IllegalArgumentException if c is not in the Base64 Alphabet.

	int result;

	if (c >= base64ToInt.length)
	    result = -1;
        else
	    result = base64ToInt[c];

        if (result < 0)
            throw new IllegalArgumentException("Illegal character " + c);
        return result;
    
public synchronized voidclose()


	// Return if already cleanly closed.
	//
	final boolean tracing = logger.traceOn();
	final boolean debug   = logger.debugOn();
	final String  idstr   = (tracing?"["+this.toString()+"]":null);

	synchronized(terminationLock) {
	    if (terminated) {
		if (closeException == null) {
		    if (tracing) logger.trace("close",idstr + " already closed.");
		    return;
		}
	    } else {
		terminated = true;
	    }
	}

	if (closeException != null && tracing) {
	    // Already closed, but not cleanly. Attempt again.
	    //
	    if (tracing) {
		logger.trace("close",idstr + " had failed: " + closeException);
		logger.trace("close",idstr + " attempting to close again.");
	    }
	}

        String savedConnectionId = null;
	if (connected) {
	    savedConnectionId = connectionId;
	}

	closeException = null;

	if (tracing) logger.trace("close",idstr + " closing.");

	if (communicatorAdmin != null) {
	    communicatorAdmin.terminate();
	}

	if (rmiNotifClient != null) {
	    try {
		rmiNotifClient.terminate();
		if (tracing) logger.trace("close",idstr +
				    " RMI Notification client terminated.");
	    } catch (RuntimeException x) {
		closeException = x;
		if (tracing) logger.trace("close",idstr +
			 " Failed to terminate RMI Notification client: " + x);
		if (debug) logger.debug("close",x);
	    }
	}

	if (connection != null) {
	    try {
		connection.close();
		if (tracing) logger.trace("close",idstr + " closed.");
	    } catch (NoSuchObjectException nse) {
		// OK, the server maybe closed itself.
	    } catch (IOException e) {
		closeException = e;
		if (tracing) logger.trace("close",idstr +
					  " Failed to close RMIServer: " + e);
		if (debug) logger.debug("close",e);
	    }
	}

	// Clean up MBeanServerConnection table
	//
	rmbscMap.clear();

	/* Send notification of closure.  We don't do this if the user
	 * never called connect() on the connector, because there's no
	 * connection id in that case.  */

	if (savedConnectionId != null) {
	    Notification closedNotif =
		new JMXConnectionNotification(JMXConnectionNotification.CLOSED,
					      this,
					      savedConnectionId,
					      clientNotifID++,
					      "Client has been closed",
					      null);
	    sendNotification(closedNotif);
	}

	// throw exception if needed
	//
	if (closeException != null) {
	    if (tracing) logger.trace("close",idstr + " failed to close: " +
			       closeException);
	    if (closeException instanceof IOException)
		throw (IOException) closeException;
	    if (closeException instanceof RuntimeException)
		throw (RuntimeException) closeException;
	    final IOException x =
		new IOException("Failed to close: " + closeException);
	    throw (IOException) EnvHelp.initCause(x,closeException);
	}
    
public voidconnect()

	connect(null);
    
public synchronized voidconnect(java.util.Map environment)

	final boolean tracing = logger.traceOn();
	String        idstr   = (tracing?"["+this.toString()+"]":null);

        if (terminated) {
	    logger.trace("connect",idstr + " already closed.");
	    throw new IOException("Connector closed");
	}
        if (connected) {
	    logger.trace("connect",idstr + " already connected.");
            return;
	}

        try {
	    if (tracing) logger.trace("connect",idstr + " connecting...");

            final Map usemap =
		new HashMap((this.env==null)?Collections.EMPTY_MAP:this.env);

            if (environment != null) {
		EnvHelp.checkAttributes(environment);
                usemap.putAll(environment);
            }

            // Get RMIServer stub from directory or URL encoding if needed.
	    if (tracing) logger.trace("connect",idstr + " finding stub...");
            RMIServer stub = (rmiServer!=null)?rmiServer:
                findRMIServer(jmxServiceURL, usemap);

            // Connect IIOP Stub if needed.
	    if (tracing) logger.trace("connect",idstr + " connecting stub...");
            stub = connectStub(stub,usemap);
	    idstr = (tracing?"["+this.toString()+"]":null);

            // Calling newClient on the RMIServer stub.
	    if (tracing) 
		logger.trace("connect",idstr + " getting connection...");
	    Object credentials = usemap.get(CREDENTIALS);
            connection = getConnection(stub, credentials);

            // Always use one of:
            //   ClassLoader provided in Map at connect time,
            //   or contextClassLoader at connect time.
	    if (tracing) 
		logger.trace("connect",idstr + " getting class loader...");
            defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap);

            usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
                       defaultClassLoader);

	    rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap);

	    env = usemap;
	    final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
	    communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);

            connected = true;

	    // The connectionId variable is used in doStart(), when 
	    // reconnecting, to identify the "old" connection.
	    //
	    connectionId = getConnectionId();

	    Notification connectedNotif =
		new JMXConnectionNotification(JMXConnectionNotification.OPENED,
					      this,
					      connectionId,
					      clientNotifID++,
					      "Successful connection",
					      null);
	    sendNotification(connectedNotif);

	    if (tracing) logger.trace("connect",idstr + " done...");
        } catch (IOException e) {
	    if (tracing) 
		logger.trace("connect",idstr + " failed to connect: " + e);
            throw e;
        } catch (RuntimeException e) {
	    if (tracing) 
		logger.trace("connect",idstr + " failed to connect: " + e);
            throw e;
        } catch (NamingException e) {
            final String msg = "Failed to retrieve RMIServer stub: " + e;
	    if (tracing) logger.trace("connect",idstr + " " + msg);
            throw (IOException) EnvHelp.initCause(new IOException(msg),e);
        }
    
static javax.management.remote.rmi.RMIServerconnectStub(javax.management.remote.rmi.RMIServer rmiServer, java.util.Map environment)

In order to be usable, an IIOP stub must be connected to an ORB. The stub is automagically connected to the ORB if:

  • It was returned by the COS naming
  • Its server counterpart has been registered in COS naming through JNDI.
Otherwise, it is not connected. A stub which is deserialized from Jini is not connected. A stub which is obtained from a non registered RMIIIOPServerImpl is not a connected.
A stub which is not connected can't be serialized, and thus can't be registered in Jini. A stub which is not connected can't be used to invoke methods on the server.

In order to palliate this, this method will connect the given stub if it is not yet connected. If the given RMIServer is not an instance of {@link javax.rmi.CORBA.Stub javax.rmi.CORBA.Stub}, then the method do nothing and simply returns that stub. Otherwise, this method will attempt to connect the stub to an ORB as follows:

    This method looks in the provided environment for the "java.naming.corba.orb" property. If it is found, the referenced object (an {@link org.omg.CORBA.ORB ORB}) is used to connect the stub. Otherwise, a new org.omg.CORBA.ORB is created by calling {@link org.omg.CORBA.ORB#init(String[], Properties) org.omg.CORBA.ORB.init((String[])null,(Properties)null)}

    The new created ORB is kept in a static {@link WeakReference} and can be reused for connecting other stubs. However, no reference is ever kept on the ORB provided in the environment map, if any.

param
rmiServer A RMI Server Stub.
param
environment An environment map, possibly containing an ORB.
return
the given stub.
exception
IllegalArgumentException if the java.naming.corba.orb property is specified and does not point to an {@link org.omg.CORBA.ORB ORB}.
exception
IOException if the connection to the ORB failed.

        if (rmiServer instanceof javax.rmi.CORBA.Stub) {
            javax.rmi.CORBA.Stub stub = (javax.rmi.CORBA.Stub) rmiServer;
            try {
                stub._orb();
            } catch (org.omg.CORBA.BAD_OPERATION x) {
                stub.connect(resolveOrb(environment));
            }
        }
        return rmiServer;
    
private javax.management.remote.rmi.RMIServerfindRMIServer(javax.management.remote.JMXServiceURL directoryURL, java.util.Map environment)

        final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true);
        if (isIiop) {
            // Make sure java.naming.corba.orb is in the Map.
            environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment));
        }

	String path = directoryURL.getURLPath();
	if (path.startsWith("/jndi/"))
	    return findRMIServerJNDI(path.substring(6), environment, isIiop);
	else if (path.startsWith("/stub/"))
	    return findRMIServerJRMP(path.substring(6), environment, isIiop);
	else if (path.startsWith("/ior/"))
	    return findRMIServerIIOP(path.substring(5), environment, isIiop);
	else {
	    final String msg = "URL path must begin with /jndi/ or /stub/ " +
		"or /ior/: " + path;
	    throw new MalformedURLException(msg);
	}
    
private javax.management.remote.rmi.RMIServerfindRMIServerIIOP(java.lang.String ior, java.util.Map env, boolean isIiop)

	// could forbid "rmi:" URL here -- but do we need to?
	final org.omg.CORBA.ORB orb = (org.omg.CORBA.ORB)
	    env.get(EnvHelp.DEFAULT_ORB);
	final Object stub = orb.string_to_object(ior);
	return (RMIServer) PortableRemoteObject.narrow(stub, RMIServer.class);
    
private javax.management.remote.rmi.RMIServerfindRMIServerJNDI(java.lang.String jndiURL, java.util.Map env, boolean isIiop)
Lookup the RMIServer stub in a directory.

param
jndiURL A JNDI URL indicating the location of the Stub (see {@link javax.management.remote.rmi}), e.g.:
  • rmi://registry-host:port/rmi-stub-name
  • or iiop://cosnaming-host:port/iiop-stub-name
  • or ldap://ldap-host:port/java-container-dn
param
env the environment Map passed to the connector.
param
isIiop true if the stub is expected to be an IIOP stub.
return
The retrieved RMIServer stub.
exception
NamingException if the stub couldn't be found.


	InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env));

	Object objref = ctx.lookup(jndiURL);
	ctx.close();

	if (isIiop)
	    return narrowIIOPServer(objref);
	else
	    return narrowJRMPServer(objref);
    
private javax.management.remote.rmi.RMIServerfindRMIServerJRMP(java.lang.String base64, java.util.Map env, boolean isIiop)

	// could forbid "iiop:" URL here -- but do we need to?
	final byte[] serialized;
	try {
	    serialized = base64ToByteArray(base64);
	} catch (IllegalArgumentException e) {
	    throw new MalformedURLException("Bad BASE64 encoding: " +
					    e.getMessage());
	}
	final ByteArrayInputStream bin = new ByteArrayInputStream(serialized);

	final ClassLoader loader = EnvHelp.resolveClientClassLoader(env);
	final ObjectInputStream oin =
	    (loader == null) ?
		new ObjectInputStream(bin) :
		new ObjectInputStreamWithLoader(bin, loader);
	final Object stub;
	try {
	    stub = oin.readObject();
	} catch (ClassNotFoundException e) {
	    throw new MalformedURLException("Class not found: " + e);
	}
	return (RMIServer) PortableRemoteObject.narrow(stub, RMIServer.class);
    
private static javax.management.remote.rmi.RMIConnectiongetConnection(javax.management.remote.rmi.RMIServer server, java.lang.Object credentials)

	RMIConnection c = server.newClient(credentials);
	try {
	    if (c.getClass() == rmiConnectionImplStubClass)
		return shadowJrmpStub((RemoteObject) c);
	    if (c.getClass().getName().equals(iiopConnectionStubClassName))
		return shadowIiopStub((Stub) c);
	    logger.trace("getConnection",
			 "Did not wrap " + c.getClass() + " to foil " +
			 "stack search for classes: class loading semantics " +
			 "may be incorrect");
	} catch (Exception e) {
	    logger.error("getConnection",
			 "Could not wrap " + c.getClass() + " to foil " +
			 "stack search for classes: class loading semantics " +
			 "may be incorrect: " + e);
	    logger.debug("getConnection",e);
	    // so just return the original stub, which will work for all
	    // but the most exotic class loading situations
	}
	return c;
    
public synchronized java.lang.StringgetConnectionId()

        if (terminated || !connected) {
	    if (logger.traceOn())
		logger.trace("getConnectionId","["+this.toString()+
		      "] not connected.");

            throw new IOException("Not connected");
	}

	// we do a remote call to have an IOException if the connection is broken.
	// see the bug 4939578
	return connection.getConnectionId();
    
public synchronized javax.management.MBeanServerConnectiongetMBeanServerConnection()

	return getMBeanServerConnection(null);
    
public synchronized javax.management.MBeanServerConnectiongetMBeanServerConnection(javax.security.auth.Subject delegationSubject)


        if (terminated) {
	    if (logger.traceOn())
		logger.trace("getMBeanServerConnection","[" + this.toString() +
		      "] already closed.");
	    throw new IOException("Connection closed");
	} else if (!connected) {
	    if (logger.traceOn())
		logger.trace("getMBeanServerConnection","[" + this.toString() +
		      "] is not connected.");
	    throw new IOException("Not connected");
	}

	MBeanServerConnection mbsc =
	    (MBeanServerConnection) rmbscMap.get(delegationSubject);
	if (mbsc != null)
	    return mbsc;

	mbsc = new RemoteMBeanServerConnection(delegationSubject);
	rmbscMap.put(delegationSubject, mbsc);
	return mbsc;
    
private voidinitTransients()

	rmbscMap = new WeakHashMap();
        connected = false;
        terminated = false;
	terminationLock = new int[0];

	connectionBroadcaster = new NotificationBroadcasterSupport();
    
private static javax.management.remote.rmi.RMIServernarrowIIOPServer(java.lang.Object objref)

        try {
            return (RMIServer)
                PortableRemoteObject.narrow(objref, RMIServer.class);
        } catch (ClassCastException e) {
            if (logger.traceOn())
		logger.trace("narrowIIOPServer","Failed to narrow objref=" +
		      objref + ": " + e);
	    if (logger.debugOn()) logger.debug("narrowIIOPServer",e);
            return null;
        }
    
private static javax.management.remote.rmi.RMIServernarrowJRMPServer(java.lang.Object objref)


        return (RMIServer) objref;
    
private static java.lang.Stringobjects(java.lang.Object[] objs)

     
	try {
	    delegateName =
		new ObjectName("JMImplementation:type=MBeanServerDelegate");
	} catch (MalformedObjectNameException e) {
	    Error error = new Error("Can't initialize delegateName");
	    EnvHelp.initCause(error, e);
	    throw error;
	}
    
	if (objs == null)
	    return "null";
	else
	    return Arrays.asList(objs).toString();
    
private voidpopDefaultClassLoader(java.lang.ClassLoader old)

	AccessController.doPrivileged(new PrivilegedAction() {
		public Object run() {
		    Thread.currentThread().setContextClassLoader(old);
		    return null;
		}
	    });
    
private java.lang.ClassLoaderpushDefaultClassLoader()


    //--------------------------------------------------------------------
    // Private stuff - Find / Set default class loader
    //--------------------------------------------------------------------
       
	final Thread t = Thread.currentThread();
        final ClassLoader old =  t.getContextClassLoader();
        if (defaultClassLoader != null)
	    AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			t.setContextClassLoader(defaultClassLoader);
			return null;
		    }
		});
        return old;
    
private voidreadObject(java.io.ObjectInputStream s)
Read RMIConnector fields from an {@link java.io.ObjectInputStream ObjectInputStream}. Calls s.defaultReadObject() and then initializes all transient variables that need initializing.

param
s The ObjectInputStream to read from.
exception
InvalidObjectException if none of rmiServer stub or jmxServiceURL are set.
see
#RMIConnector(JMXServiceURL,Map)
see
#RMIConnector(RMIServer,Map)

        s.defaultReadObject();

        if (rmiServer == null && jmxServiceURL == null) throw new
          InvalidObjectException("rmiServer and jmxServiceURL both null");

	initTransients();
    
public voidremoveConnectionNotificationListener(javax.management.NotificationListener listener)

	if (listener == null) 
	    throw new NullPointerException("listener");
	connectionBroadcaster.removeNotificationListener(listener);
    
public voidremoveConnectionNotificationListener(javax.management.NotificationListener listener, javax.management.NotificationFilter filter, java.lang.Object handback)

	if (listener == null) 
	    throw new NullPointerException("listener");
	connectionBroadcaster.removeNotificationListener(listener, filter,
							 handback);
    
static org.omg.CORBA.ORBresolveOrb(java.util.Map environment)
Get the ORB specified by environment, or create a new one.

This method looks in the provided environment for the "java.naming.corba.orb" property. If it is found, the referenced object (an {@link org.omg.CORBA.ORB ORB}) is returned. Otherwise, a new org.omg.CORBA.ORB is created by calling {@link org.omg.CORBA.ORB#init(String[], java.util.Properties) org.omg.CORBA.ORB.init((String[])null,(Properties)null)}

The new created ORB is kept in a static {@link WeakReference} and can be reused for connecting other stubs. However, no reference is ever kept on the ORB provided in the environment map, if any.

param
environment An environment map, possibly containing an ORB.
return
An ORB.
exception
IllegalArgumentException if the java.naming.corba.orb property is specified and does not point to an {@link org.omg.CORBA.ORB ORB}.
exception
IOException if the ORB initialization failed.

        if (environment != null) {
            final Object orb = environment.get(EnvHelp.DEFAULT_ORB);
            if (orb != null && !(orb instanceof  org.omg.CORBA.ORB))
                throw new IllegalArgumentException(EnvHelp.DEFAULT_ORB +
                          " must be an instance of org.omg.CORBA.ORB.");
            if (orb != null) return (org.omg.CORBA.ORB)orb;
        }
        final Object orb =
            (RMIConnector.orb==null)?null:RMIConnector.orb.get();
        if (orb != null) return (org.omg.CORBA.ORB)orb;

        final org.omg.CORBA.ORB newOrb =
            org.omg.CORBA.ORB.init((String[])null, (Properties)null);
        RMIConnector.orb = new WeakReference(newOrb);
        return newOrb;
    
private voidsendNotification(javax.management.Notification n)

	connectionBroadcaster.sendNotification(n);
    
private static javax.management.remote.rmi.RMIConnectionshadowIiopStub(javax.rmi.CORBA.Stub stub)

     
	final String proxyStubByteCodeString =
	    "\312\376\272\276\0\0\0.\0)\12\0\14\0\26\7\0\27\12\0\14\0\30\12"+
	    "\0\2\0\31\7\0\32\12\0\5\0\33\12\0\5\0\34\12\0\5\0\35\12\0\2\0"+
	    "\36\12\0\14\0\37\7\0\40\7\0!\1\0\6<init>\1\0\3()V\1\0\4Code\1"+
	    "\0\7_invoke\1\0K(Lorg/omg/CORBA/portable/OutputStream;)Lorg/o"+
	    "mg/CORBA/portable/InputStream;\1\0\12Exceptions\7\0\"\1\0\15_"+
	    "releaseReply\1\0'(Lorg/omg/CORBA/portable/InputStream;)V\14\0"+
	    "\15\0\16\1\0(com/sun/jmx/remote/internal/PInputStream\14\0\20"+
	    "\0\21\14\0\15\0\25\1\0+org/omg/CORBA/portable/ApplicationExce"+
	    "ption\14\0#\0$\14\0%\0&\14\0\15\0'\14\0(\0$\14\0\24\0\25\1\0%"+
	    "com/sun/jmx/remote/internal/ProxyStub\1\0<org/omg/stub/javax/"+
	    "management/remote/rmi/_RMIConnection_Stub\1\0)org/omg/CORBA/p"+
	    "ortable/RemarshalException\1\0\16getInputStream\1\0&()Lorg/om"+
	    "g/CORBA/portable/InputStream;\1\0\5getId\1\0\24()Ljava/lang/S"+
	    "tring;\1\09(Ljava/lang/String;Lorg/omg/CORBA/portable/InputSt"+
	    "ream;)V\1\0\25getProxiedInputStream\0!\0\13\0\14\0\0\0\0\0\3\0"+
	    "\1\0\15\0\16\0\1\0\17\0\0\0\21\0\1\0\1\0\0\0\5*\267\0\1\261\0"+
	    "\0\0\0\0\1\0\20\0\21\0\2\0\17\0\0\0;\0\4\0\4\0\0\0'\273\0\2Y*"+
	    "+\267\0\3\267\0\4\260M\273\0\2Y,\266\0\6\267\0\4N\273\0\5Y,\266"+
	    "\0\7-\267\0\10\277\0\1\0\0\0\14\0\15\0\5\0\0\0\22\0\0\0\6\0\2"+
	    "\0\5\0\23\0\1\0\24\0\25\0\1\0\17\0\0\0\36\0\2\0\2\0\0\0\22+\306"+
	    "\0\13+\300\0\2\266\0\11L*+\267\0\12\261\0\0\0\0\0\0";
	final String pInputStreamByteCodeString =
	    "\312\376\272\276\0\0\0.\0\36\12\0\7\0\17\11\0\6\0\20\12\0\21\0"+
	    "\22\12\0\6\0\23\12\0\24\0\25\7\0\26\7\0\27\1\0\6<init>\1\0'(L"+
	    "org/omg/CORBA/portable/InputStream;)V\1\0\4Code\1\0\10read_an"+
	    "y\1\0\25()Lorg/omg/CORBA/Any;\1\0\12read_value\1\0)(Ljava/lan"+
	    "g/Class;)Ljava/io/Serializable;\14\0\10\0\11\14\0\30\0\31\7\0"+
	    "\32\14\0\13\0\14\14\0\33\0\34\7\0\35\14\0\15\0\16\1\0(com/sun"+
	    "/jmx/remote/internal/PInputStream\1\0,com/sun/jmx/remote/inte"+
	    "rnal/ProxyInputStream\1\0\2in\1\0$Lorg/omg/CORBA/portable/Inp"+
	    "utStream;\1\0\"org/omg/CORBA/portable/InputStream\1\0\6narrow"+
	    "\1\0*()Lorg/omg/CORBA_2_3/portable/InputStream;\1\0&org/omg/C"+
	    "ORBA_2_3/portable/InputStream\0!\0\6\0\7\0\0\0\0\0\3\0\1\0\10"+
	    "\0\11\0\1\0\12\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261\0\0\0\0"+
	    "\0\1\0\13\0\14\0\1\0\12\0\0\0\24\0\1\0\1\0\0\0\10*\264\0\2\266"+
	    "\0\3\260\0\0\0\0\0\1\0\15\0\16\0\1\0\12\0\0\0\25\0\2\0\2\0\0\0"+
	    "\11*\266\0\4+\266\0\5\260\0\0\0\0\0\0";
	final byte[] proxyStubByteCode =
	    NoCallStackClassLoader.stringToBytes(proxyStubByteCodeString);
	final byte[] pInputStreamByteCode =
	    NoCallStackClassLoader.stringToBytes(pInputStreamByteCodeString);
	final String[] classNames={proxyStubClassName, pInputStreamClassName};
	final byte[][] byteCodes = {proxyStubByteCode, pInputStreamByteCode};
	final String[] otherClassNames = {
	    iiopConnectionStubClassName,
	    ProxyInputStream.class.getName(),
	};
	PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
	    public Object run() throws Exception {
		Class thisClass = RMIConnector.class;
		ClassLoader thisLoader = thisClass.getClassLoader();
		ProtectionDomain thisProtectionDomain =
		    thisClass.getProtectionDomain();
		ClassLoader cl =
		    new NoCallStackClassLoader(classNames,
					       byteCodes,
					       otherClassNames,
					       thisLoader,
					       thisProtectionDomain);
		return cl.loadClass(proxyStubClassName);
	    }
	};
	Class stubClass;
	try {
	    stubClass = (Class) AccessController.doPrivileged(action);
	} catch (Exception e) {
	    logger.error("<clinit>",
		   "Unexpected exception making shadow IIOP stub class: "+e);
	    logger.debug("<clinit>",e);
	    stubClass = null;
	}
	proxyStubClass = stubClass;
    
	Stub proxyStub = (Stub) proxyStubClass.newInstance();
	proxyStub._set_delegate(stub._get_delegate());
	return (RMIConnection) proxyStub;
    
private static javax.management.remote.rmi.RMIConnectionshadowJrmpStub(java.rmi.server.RemoteObject stub)

     
	final String pRefByteCodeString =
	    "\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+
	    "\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/RemoteRef;"+
	    ")V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/reflec"+
	    "t/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12Exception"+
	    "s\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1\0\40com/"+
	    "sun/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/internal/Pr"+
	    "oxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rmi/serve"+
	    "r/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5\0\0\0\0"+
	    "\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261"+
	    "\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0\6\0\0\0\17*\264\0"+
	    "\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0\4\0\1\0\14\0\0";
	final byte[] pRefByteCode =
	    NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
	PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
	    public Object run() throws Exception {
		Class thisClass = RMIConnector.class;
		ClassLoader thisLoader = thisClass.getClassLoader();
		ProtectionDomain thisProtectionDomain =
		    thisClass.getProtectionDomain();
		String[] otherClassNames = {ProxyRef.class.getName()};
		ClassLoader cl =
		    new NoCallStackClassLoader(pRefClassName,
					       pRefByteCode,
					       otherClassNames,
					       thisLoader,
					       thisProtectionDomain);
		Class c = cl.loadClass(pRefClassName);
		return c.getConstructor(new Class[] {RemoteRef.class});
	    }
	};

	Class stubClass;
	Constructor constr;
	try {
	    stubClass = Class.forName(rmiConnectionImplStubClassName);
	    constr = (Constructor) AccessController.doPrivileged(action);
	} catch (Exception e) {
	    logger.error("<clinit>", 
			 "Failed to initialize proxy reference consructor "+
			 "for " + rmiConnectionImplStubClassName + ": " + e);
	    logger.debug("<clinit>",e);
	    stubClass = null;
	    constr = null;
	}
	rmiConnectionImplStubClass = stubClass;
	proxyRefConstructor = constr;
    
	RemoteRef ref = stub.getRef();
	RemoteRef proxyRef = (RemoteRef)
	    proxyRefConstructor.newInstance(new Object[] {ref});
	final Class[] constrTypes = {RemoteRef.class};
	final Constructor rmiConnectionImplStubConstructor =
	    rmiConnectionImplStubClass.getConstructor(constrTypes);
	Object[] args = {proxyRef};
	RMIConnection proxyStub = (RMIConnection)
	    rmiConnectionImplStubConstructor.newInstance(args);
	return proxyStub;
    
private static java.lang.Stringstrings(java.lang.String[] strs)

	return objects(strs);
    
public java.lang.StringtoString()

Returns a string representation of this object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read.

return
a String representation of this object.

        final StringBuffer b = new StringBuffer(this.getClass().getName());
        b.append(":");
        if (rmiServer != null) {
            b.append(" rmiServer=").append(rmiServer.toString());
        }
        if (jmxServiceURL != null) {
            if (rmiServer!=null) b.append(",");
            b.append(" jmxServiceURL=").append(jmxServiceURL.toString());
        }
        return b.toString();
    
private voidwriteObject(java.io.ObjectOutputStream s)
Writes the RMIConnector fields to an {@link java.io.ObjectOutputStream ObjectOutputStream}.

Connects the underlying RMIServer stub to an ORB, if needed, before serializing it. This is done using the environment map that was provided to the constructor, if any, and as documented in {@link javax.management.remote.rmi}.

This method then calls s.defaultWriteObject(). Usually, rmiServer is null if this object was constructed with a JMXServiceURL, and jmxServiceURL is null if this object is constructed with a RMIServer stub.

Note that the environment Map is not serialized, since the objects it contains are assumed to be contextual and relevant only with respect to the local environment (class loader, ORB, etc...).

After an RMIConnector is deserialized, it is assumed that the user will call {@link #connect(Map)}, providing a new Map that can contain values which are contextually relevant to the new local environment.

Since connection to the ORB is needed prior to serializing, and since the ORB to connect to is one of those contextual parameters, it is not recommended to re-serialize a just de-serialized object - as the de-serialized object has no map. Thus, when an RMIConnector object is needed for serialization or transmission to a remote application, it is recommended to obtain a new RMIConnector stub by calling {@link RMIConnectorServer#toJMXConnector(Map)}.

param
s The ObjectOutputStream to write to.
exception
InvalidObjectException if none of rmiServer stub or jmxServiceURL are set.
see
#RMIConnector(JMXServiceURL,Map)
see
#RMIConnector(RMIServer,Map)

        if (rmiServer == null && jmxServiceURL == null) throw new
          InvalidObjectException("rmiServer and jmxServiceURL both null.");
        connectStub(this.rmiServer,env);
        s.defaultWriteObject();