Methods Summary |
---|
protected void | clientClosed(javax.management.remote.rmi.RMIConnection client)Method called when a client connection created by {@link
#makeClient makeClient} is closed. A subclass that defines
makeClient must arrange for this method to be
called when the resultant object's {@link RMIConnection#close()
close} method is called. This enables it to be removed from
the RMIServerImpl 's list of connections. It is
not an error for client not to be in that
list.
After removing client from the list of
connections, this method calls {@link #closeClient
closeClient(client)}.
final boolean debug = logger.debugOn();
if (debug) logger.trace("clientClosed","client="+client);
if (client == null)
throw new NullPointerException("Null client");
synchronized (clientList) {
dropDeadReferences();
for (Iterator it = clientList.iterator(); it.hasNext(); ) {
WeakReference wr = (WeakReference) it.next();
if (wr.get() == client) {
it.remove();
break;
}
}
/* It is not a bug for this loop not to find the client. In
our close() method, we remove a client from the list before
calling its close() method. */
}
if (debug) logger.trace("clientClosed", "closing client.");
closeClient(client);
if (debug) logger.trace("clientClosed", "sending notif");
connServer.connectionClosed(client.getConnectionId(),
"Client connection closed", null);
if (debug) logger.trace("clientClosed","done");
|
public synchronized void | close()Closes this connection server. This method first calls the
{@link #closeServer()} method so that no new client connections
will be accepted. Then, for each remaining {@link
RMIConnection} object returned by {@link #makeClient
makeClient}, its {@link RMIConnection#close() close} method is
called.
The behaviour when this method is called more than once is
unspecified.
If {@link #closeServer()} throws an
IOException , the individual connections are
nevertheless closed, and then the IOException is
thrown from this method.
If {@link #closeServer()} returns normally but one or more
of the individual connections throws an
IOException , then, after closing all the
connections, one of those IOException s is thrown
from this method. If more than one connection throws an
IOException , it is unspecified which one is thrown
from this method.
final boolean tracing = logger.traceOn();
final boolean debug = logger.debugOn();
if (tracing) logger.trace("close","closing");
IOException ioException = null;
try {
if (debug) logger.debug("close","closing Server");
closeServer();
} catch (IOException e) {
if (tracing) logger.trace("close","Failed to close server: " + e);
if (debug) logger.debug("close",e);
ioException = e;
}
if (debug) logger.debug("close","closing Clients");
// Loop to close all clients
while (true) {
synchronized (clientList) {
if (debug) logger.debug("close","droping dead references");
dropDeadReferences();
if (debug) logger.debug("close","client count: "+clientList.size());
if (clientList.size() == 0)
break;
/* Loop until we find a non-null client. Because we called
dropDeadReferences(), this will usually be the first
element of the list, but a garbage collection could have
happened in between. */
for (Iterator it = clientList.iterator(); it.hasNext(); ) {
WeakReference wr = (WeakReference) it.next();
RMIConnection client = (RMIConnection) wr.get();
it.remove();
if (client != null) {
try {
client.close();
} catch (IOException e) {
if (tracing)
logger.trace("close","Failed to close client: " + e);
if (debug) logger.debug("close",e);
if (ioException == null)
ioException = e;
}
break;
}
}
}
}
if(notifBuffer != null)
notifBuffer.dispose();
if (ioException != null) {
if (tracing) logger.trace("close","close failed.");
throw ioException;
}
if (tracing) logger.trace("close","closed.");
|
protected abstract void | closeClient(javax.management.remote.rmi.RMIConnection client)Closes a client connection made by {@link #makeClient makeClient}.
|
protected abstract void | closeServer()Called by {@link #close()} to close the connector server.
After returning from this method, the connector server must
not accept any new connections.
|
private javax.management.remote.rmi.RMIConnection | doNewClient(java.lang.Object credentials)
final boolean tracing = logger.traceOn();
if (tracing) logger.trace("newClient","making new client");
if (getMBeanServer() == null)
throw new IllegalStateException("Not attached to an MBean server");
Subject subject = null;
JMXAuthenticator authenticator =
(JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
if (authenticator == null) {
/*
* Create the JAAS-based authenticator only if authentication
* has been enabled
*/
if (env.get("jmx.remote.x.password.file") != null ||
env.get("jmx.remote.x.login.config") != null) {
authenticator = new JMXPluggableAuthenticator(env);
}
}
if (authenticator != null) {
if (tracing) logger.trace("newClient","got authenticator: " +
authenticator.getClass().getName());
try {
subject = authenticator.authenticate(credentials);
} catch (SecurityException e) {
logger.trace("newClient", "Authentication failed: " + e);
throw e;
}
}
if (tracing) {
if (subject != null)
logger.trace("newClient","subject is not null");
else logger.trace("newClient","no subject");
}
final String connectionId = makeConnectionId(getProtocol(), subject);
if (tracing)
logger.trace("newClient","making new connection: " + connectionId);
RMIConnection client = makeClient(connectionId, subject);
connServer.connectionOpened(connectionId, "Connection opened", null);
dropDeadReferences();
WeakReference wr = new WeakReference(client);
synchronized (clientList) {
clientList.add(wr);
}
if (tracing)
logger.trace("newClient","new connection done: " + connectionId );
return client;
|
private void | dropDeadReferences()
synchronized (clientList) {
for (Iterator it = clientList.iterator(); it.hasNext(); ) {
WeakReference wr = (WeakReference) it.next();
if (wr.get() == null)
it.remove();
}
}
|
protected abstract void | export()Exports this RMI object.
|
public synchronized java.lang.ClassLoader | getDefaultClassLoader()Gets the default ClassLoader used by this connector
server.
return cl;
|
public synchronized javax.management.MBeanServer | getMBeanServer()The MBeanServer to which this connector server
is attached. This is the last value passed to {@link
#setMBeanServer} on this object, or null if that method has
never been called.
return mbeanServer;
|
synchronized com.sun.jmx.remote.internal.NotificationBuffer | getNotifBuffer()
//Notification buffer is lazily created when the first client connects
if(notifBuffer == null)
notifBuffer =
ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
env);
return notifBuffer;
|
protected abstract java.lang.String | getProtocol()Returns the protocol string for this object. The string is
rmi for RMI/JRMP and iiop for RMI/IIOP.
|
public java.lang.String | getVersion()
// Expected format is: "protocol-version implementation-name"
return "1.0 java_runtime_" + (String)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty("java.runtime.version");
}
});
|
protected abstract javax.management.remote.rmi.RMIConnection | makeClient(java.lang.String connectionId, javax.security.auth.Subject subject)Creates a new client connection. This method is called by
the public method {@link #newClient(Object)}.
|
private static synchronized java.lang.String | makeConnectionId(java.lang.String protocol, javax.security.auth.Subject subject)
connectionIdNumber++;
String clientHost = "";
try {
clientHost = RemoteServer.getClientHost();
} catch (ServerNotActiveException e) {
logger.trace("makeConnectionId", "getClientHost", e);
}
StringBuffer buf = new StringBuffer();
buf.append(protocol).append(":");
if (clientHost.length() > 0)
buf.append("//").append(clientHost);
buf.append(" ");
if (subject != null) {
Set principals = subject.getPrincipals();
String sep = "";
for (Iterator it = principals.iterator(); it.hasNext(); ) {
Principal p = (Principal) it.next();
String name = p.getName().replace(' ", '_").replace(';", ':");
buf.append(sep).append(name);
sep = ";";
}
}
buf.append(" ").append(connectionIdNumber);
if (logger.traceOn())
logger.trace("newConnectionId","connectionId="+buf);
return buf.toString();
|
public javax.management.remote.rmi.RMIConnection | newClient(java.lang.Object credentials)Creates a new client connection. This method calls {@link
#makeClient makeClient} and adds the returned client connection
object to an internal list. When this
RMIServerImpl is shut down via its {@link
#close()} method, the {@link RMIConnection#close() close()}
method of each object remaining in the list is called.
The fact that a client connection object is in this internal
list does not prevent it from being garbage collected.
try {
final Object o = credentials;
return AccessController.doPrivileged(
new PrivilegedExceptionAction<RMIConnection>() {
public RMIConnection run() throws IOException {
return doNewClient(o);
}
}, callerACC);
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getCause();
}
|
public synchronized void | setDefaultClassLoader(java.lang.ClassLoader cl)Sets the default ClassLoader for this connector
server. New client connections will use this classloader.
Existing client connections are unaffected.
this.cl = cl;
|
public synchronized void | setMBeanServer(javax.management.MBeanServer mbs)Sets the MBeanServer to which this connector
server is attached. New client connections will interact
with this MBeanServer . Existing client connections are
unaffected.
this.mbeanServer = mbs;
|
void | setRMIConnectorServer(javax.management.remote.rmi.RMIConnectorServer connServer)
this.connServer = connServer;
|
public abstract java.rmi.Remote | toStub()Returns a remotable stub for this server object.
|