An RMI object representing a connector server. Remote clients
can make connections using the #newClient(Object) method. This
method returns an RMI object representing the connection.
This is an abstract class. Concrete subclasses define the
details of the client connection objects, such as whether they use
JRMP or IIOP.
| Method from javax.management.remote.rmi.RMIServerImpl Detail: |
protected void clientClosed(RMIConnection client) throws IOException {
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");
}
Method called when a client connection created by makeClient is closed. A subclass that defines
makeClient must arrange for this method to be
called when the resultant object's 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 closeClient(client) .
|
public synchronized void close() throws IOException {
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.");
}
Closes this connection server. This method first calls the
#closeServer() method so that no new client connections
will be accepted. Then, for each remaining RMIConnection object returned by
makeClient , its close method is
called.
The behavior when this method is called more than once is
unspecified.
If #closeServer() throws an
IOException, the individual connections are
nevertheless closed, and then the IOException is
thrown from this method.
If #closeServer() returns normally but one or more
of the individual connections throws an
IOException, then, after closing all the
connections, one of those IOExceptions is thrown
from this method. If more than one connection throws an
IOException, it is unspecified which one is thrown
from this method.
|
abstract protected void closeClient(RMIConnection client) throws IOException
|
abstract protected void closeServer() throws IOException
Called by #close() to close the connector server.
After returning from this method, the connector server must
not accept any new connections.
|
RMIConnection doNewClient(Object credentials) throws IOException {
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< RMIConnection > wr = new WeakReference< RMIConnection >(client);
synchronized (clientList) {
clientList.add(wr);
}
if (tracing)
logger.trace("newClient","new connection done: " + connectionId );
return client;
}
This method could be overridden by subclasses defined in this package
to perform additional operations specific to the underlying transport
before creating the new client connection. |
abstract protected void export() throws IOException
|
public synchronized ClassLoader getDefaultClassLoader() {
return cl;
}
|
public synchronized MBeanServer getMBeanServer() {
return mbeanServer;
}
The MBeanServer to which this connector server
is attached. This is the last value passed to #setMBeanServer on this object, or null if that method has
never been called.
|
synchronized NotificationBuffer getNotifBuffer() {
//Notification buffer is lazily created when the first client connects
if(notifBuffer == null)
notifBuffer =
ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
env);
return notifBuffer;
}
|
abstract protected String getProtocol()
|
public String getVersion() {
// Expected format is: "protocol-version implementation-name"
try {
return "1.0 java_runtime_" +
System.getProperty("java.runtime.version");
} catch (SecurityException e) {
return "1.0 ";
}
}
|
abstract protected RMIConnection makeClient(String connectionId,
Subject subject) throws IOException
|
public RMIConnection newClient(Object credentials) throws IOException {
return doNewClient(credentials);
}
Creates a new client connection. This method calls makeClient and adds the returned client connection
object to an internal list. When this
RMIServerImpl is shut down via its #close() method, the 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.
|
public synchronized void setDefaultClassLoader(ClassLoader cl) {
this.cl = cl;
}
Sets the default ClassLoader for this connector
server. New client connections will use this classloader.
Existing client connections are unaffected.
|
public synchronized void setMBeanServer(MBeanServer mbs) {
this.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.
|
void setRMIConnectorServer(RMIConnectorServer connServer) throws IOException {
this.connServer = connServer;
}
|
abstract public Remote toStub() throws IOException
Returns a remotable stub for this server object. |