1 7 8 package javax.management.remote.rmi; 9 10 import com.sun.jmx.remote.internal.ArrayNotificationBuffer; 11 import com.sun.jmx.remote.internal.NotificationBuffer; 12 import com.sun.jmx.remote.security.JMXPluggableAuthenticator; 13 import com.sun.jmx.remote.util.ClassLogger; 14 import java.io.IOException ; 15 import java.lang.ref.WeakReference ; 16 import java.rmi.Remote ; 17 import java.rmi.server.RemoteServer ; 18 import java.rmi.server.ServerNotActiveException ; 19 import java.security.Principal ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.Set ; 26 import javax.management.MBeanServer ; 27 import javax.management.remote.JMXAuthenticator ; 28 import javax.management.remote.JMXConnectorServer ; 29 import javax.security.auth.Subject ; 30 31 49 public abstract class RMIServerImpl implements RMIServer { 50 57 public RMIServerImpl(Map <String ,?> env) { 58 this.env = (env == null) ? Collections.EMPTY_MAP : env; 59 } 60 61 void setRMIConnectorServer(RMIConnectorServer connServer) 62 throws IOException { 63 this.connServer = connServer; 64 } 65 66 71 protected abstract void export() throws IOException ; 72 73 79 public abstract Remote toStub() throws IOException ; 80 81 91 public synchronized void setDefaultClassLoader(ClassLoader cl) { 92 this.cl = cl; 93 } 94 95 104 public synchronized ClassLoader getDefaultClassLoader() { 105 return cl; 106 } 107 108 119 public synchronized void setMBeanServer(MBeanServer mbs) { 120 this.mbeanServer = mbs; 121 } 122 123 134 public synchronized MBeanServer getMBeanServer() { 135 return mbeanServer; 136 } 137 138 public String getVersion() { 139 try { 141 return "1.0 java_runtime_" + 142 System.getProperty("java.runtime.version"); 143 } catch (SecurityException e) { 144 return "1.0 "; 145 } 146 } 147 148 178 public RMIConnection newClient(Object credentials) throws IOException { 179 return doNewClient(credentials); 180 } 181 182 187 RMIConnection doNewClient(Object credentials) throws IOException { 188 final boolean tracing = logger.traceOn(); 189 190 if (tracing) logger.trace("newClient","making new client"); 191 192 if (getMBeanServer() == null) 193 throw new IllegalStateException ("Not attached to an MBean server"); 194 195 Subject subject = null; 196 JMXAuthenticator authenticator = 197 (JMXAuthenticator ) env.get(JMXConnectorServer.AUTHENTICATOR); 198 if (authenticator == null) { 199 203 if (env.get("jmx.remote.x.password.file") != null || 204 env.get("jmx.remote.x.login.config") != null) { 205 authenticator = new JMXPluggableAuthenticator(env); 206 } 207 } 208 if (authenticator != null) { 209 if (tracing) logger.trace("newClient","got authenticator: " + 210 authenticator.getClass().getName()); 211 try { 212 subject = authenticator.authenticate(credentials); 213 } catch (SecurityException e) { 214 logger.trace("newClient", "Authentication failed: " + e); 215 throw e; 216 } 217 } 218 219 if (tracing) { 220 if (subject != null) 221 logger.trace("newClient","subject is not null"); 222 else logger.trace("newClient","no subject"); 223 } 224 225 final String connectionId = makeConnectionId(getProtocol(), subject); 226 227 if (tracing) 228 logger.trace("newClient","making new connection: " + connectionId); 229 230 RMIConnection client = makeClient(connectionId, subject); 231 232 connServer.connectionOpened(connectionId, "Connection opened", null); 233 234 dropDeadReferences(); 235 WeakReference wr = new WeakReference (client); 236 synchronized (clientList) { 237 clientList.add(wr); 238 } 239 240 if (tracing) 241 logger.trace("newClient","new connection done: " + connectionId ); 242 243 return client; 244 } 245 246 262 protected abstract RMIConnection makeClient(String connectionId, 263 Subject subject) 264 throws IOException ; 265 266 278 protected abstract void closeClient(RMIConnection client) 279 throws IOException ; 280 281 287 protected abstract String getProtocol(); 288 289 310 protected void clientClosed(RMIConnection client) throws IOException { 311 final boolean debug = logger.debugOn(); 312 313 if (debug) logger.trace("clientClosed","client="+client); 314 315 if (client == null) 316 throw new NullPointerException ("Null client"); 317 318 synchronized (clientList) { 319 dropDeadReferences(); 320 for (Iterator it = clientList.iterator(); it.hasNext(); ) { 321 WeakReference wr = (WeakReference ) it.next(); 322 if (wr.get() == client) { 323 it.remove(); 324 break; 325 } 326 } 327 330 } 331 332 if (debug) logger.trace("clientClosed", "closing client."); 333 closeClient(client); 334 335 if (debug) logger.trace("clientClosed", "sending notif"); 336 connServer.connectionClosed(client.getConnectionId(), 337 "Client connection closed", null); 338 339 if (debug) logger.trace("clientClosed","done"); 340 } 341 342 370 public synchronized void close() throws IOException { 371 final boolean tracing = logger.traceOn(); 372 final boolean debug = logger.debugOn(); 373 374 if (tracing) logger.trace("close","closing"); 375 376 IOException ioException = null; 377 try { 378 if (debug) logger.debug("close","closing Server"); 379 closeServer(); 380 } catch (IOException e) { 381 if (tracing) logger.trace("close","Failed to close server: " + e); 382 if (debug) logger.debug("close",e); 383 ioException = e; 384 } 385 386 if (debug) logger.debug("close","closing Clients"); 387 while (true) { 389 synchronized (clientList) { 390 if (debug) logger.debug("close","droping dead references"); 391 dropDeadReferences(); 392 393 if (debug) logger.debug("close","client count: "+clientList.size()); 394 if (clientList.size() == 0) 395 break; 396 400 for (Iterator it = clientList.iterator(); it.hasNext(); ) { 401 WeakReference wr = (WeakReference ) it.next(); 402 RMIConnection client = (RMIConnection ) wr.get(); 403 it.remove(); 404 if (client != null) { 405 try { 406 client.close(); 407 } catch (IOException e) { 408 if (tracing) 409 logger.trace("close","Failed to close client: " + e); 410 if (debug) logger.debug("close",e); 411 if (ioException == null) 412 ioException = e; 413 } 414 break; 415 } 416 } 417 } 418 } 419 420 if(notifBuffer != null) 421 notifBuffer.dispose(); 422 423 if (ioException != null) { 424 if (tracing) logger.trace("close","close failed."); 425 throw ioException; 426 } 427 428 if (tracing) logger.trace("close","closed."); 429 } 430 431 439 protected abstract void closeServer() throws IOException ; 440 441 private static synchronized String makeConnectionId(String protocol, 442 Subject subject) { 443 connectionIdNumber++; 444 445 String clientHost = ""; 446 try { 447 clientHost = RemoteServer.getClientHost(); 448 } catch (ServerNotActiveException e) { 449 logger.trace("makeConnectionId", "getClientHost", e); 450 } 451 452 StringBuffer buf = new StringBuffer (); 453 buf.append(protocol).append(":"); 454 if (clientHost.length() > 0) 455 buf.append("//").append(clientHost); 456 buf.append(" "); 457 if (subject != null) { 458 Set principals = subject.getPrincipals(); 459 String sep = ""; 460 for (Iterator it = principals.iterator(); it.hasNext(); ) { 461 Principal p = (Principal ) it.next(); 462 String name = p.getName().replace(' ', '_').replace(';', ':'); 463 buf.append(sep).append(name); 464 sep = ";"; 465 } 466 } 467 buf.append(" ").append(connectionIdNumber); 468 if (logger.traceOn()) 469 logger.trace("newConnectionId","connectionId="+buf); 470 return buf.toString(); 471 } 472 473 private void dropDeadReferences() { 474 synchronized (clientList) { 475 for (Iterator it = clientList.iterator(); it.hasNext(); ) { 476 WeakReference wr = (WeakReference ) it.next(); 477 if (wr.get() == null) 478 it.remove(); 479 } 480 } 481 } 482 483 synchronized NotificationBuffer getNotifBuffer() { 484 if(notifBuffer == null) 486 notifBuffer = 487 ArrayNotificationBuffer.getNotificationBuffer(mbeanServer, 488 env); 489 return notifBuffer; 490 } 491 492 private static final ClassLogger logger = 493 new ClassLogger("javax.management.remote.rmi", "RMIServerImpl"); 494 495 498 private final List clientList = new ArrayList (); 499 500 private ClassLoader cl; 501 502 private MBeanServer mbeanServer; 503 504 private final Map env; 505 506 private RMIConnectorServer connServer; 507 508 private static int connectionIdNumber; 509 510 private NotificationBuffer notifBuffer; 511 } 512 | Popular Tags |