📄 rmiserverimpl.java
字号:
* @return the newly-created <code>RMIConnection</code>. * * @exception IOException if the new client object cannot be * created or exported. */ protected abstract RMIConnection makeClient(String connectionId, Subject subject) throws IOException; /** * <p>Closes a client connection made by {@link #makeClient makeClient}. * * @param client a connection previously returned by * <code>makeClient</code> on which the <code>closeClient</code> * method has not previously been called. The behavior is * unspecified if these conditions are violated, including the * case where <code>client</code> is null. * * @exception IOException if the client connection cannot be * closed. */ protected abstract void closeClient(RMIConnection client) throws IOException; /** * <p>Returns the protocol string for this object. The string is * <code>rmi</code> for RMI/JRMP and <code>iiop</code> for RMI/IIOP. * * @return the protocol string for this object. */ protected abstract String getProtocol(); /** * <p>Method called when a client connection created by {@link * #makeClient makeClient} is closed. A subclass that defines * <code>makeClient</code> 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 <code>RMIServerImpl</code>'s list of connections. It is * not an error for <code>client</code> not to be in that * list.</p> * * <p>After removing <code>client</code> from the list of * connections, this method calls {@link #closeClient * closeClient(client)}.</p> * * @param client the client connection that has been closed. * * @exception IOException if {@link #closeClient} throws this * exception. * * @exception NullPointerException if <code>client</code> is null. */ 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"); } /** * <p>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.</p> * * <p>The behavior when this method is called more than once is * unspecified.</p> * * <p>If {@link #closeServer()} throws an * <code>IOException</code>, the individual connections are * nevertheless closed, and then the <code>IOException</code> is * thrown from this method.</p> * * <p>If {@link #closeServer()} returns normally but one or more * of the individual connections throws an * <code>IOException</code>, then, after closing all the * connections, one of those <code>IOException</code>s is thrown * from this method. If more than one connection throws an * <code>IOException</code>, it is unspecified which one is thrown * from this method.</p> * * @exception IOException if {@link #closeServer()} or one of the * {@link RMIConnection#close()} calls threw * <code>IOException</code>. */ 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."); } /** * <p>Called by {@link #close()} to close the connector server. * After returning from this method, the connector server must * not accept any new connections.</p> * * @exception IOException if the attempt to close the connector * server failed. */ protected abstract void closeServer() throws IOException; private static synchronized String makeConnectionId(String protocol, 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(); } private void dropDeadReferences() { synchronized (clientList) { for (Iterator it = clientList.iterator(); it.hasNext(); ) { WeakReference wr = (WeakReference) it.next(); if (wr.get() == null) it.remove(); } } } synchronized NotificationBuffer getNotifBuffer() { //Notification buffer is lazily created when the first client connects if(notifBuffer == null) notifBuffer = ArrayNotificationBuffer.getNotificationBuffer(mbeanServer, env); return notifBuffer; } private static final ClassLogger logger = new ClassLogger("javax.management.remote.rmi", "RMIServerImpl"); /** List of WeakReference values. Each one references an RMIConnection created by this object, or null if the RMIConnection has been garbage-collected. */ private final List clientList = new ArrayList(); private ClassLoader cl; private MBeanServer mbeanServer; private final Map env; private RMIConnectorServer connServer; private static int connectionIdNumber; private NotificationBuffer notifBuffer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -