KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > remote > rmi > RMIConnector


1 /*
2  * @(#)RMIConnector.java 1.117 05/12/01
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management.remote.rmi;
9
10 // JMX
11
import javax.management.Attribute JavaDoc;
12 import javax.management.AttributeList JavaDoc;
13 import javax.management.AttributeNotFoundException JavaDoc;
14 import javax.management.InstanceAlreadyExistsException JavaDoc;
15 import javax.management.InstanceNotFoundException JavaDoc;
16 import javax.management.IntrospectionException JavaDoc;
17 import javax.management.InvalidAttributeValueException JavaDoc;
18 import javax.management.ListenerNotFoundException JavaDoc;
19 import javax.management.MalformedObjectNameException JavaDoc;
20 import javax.management.MBeanException JavaDoc;
21 import javax.management.MBeanInfo JavaDoc;
22 import javax.management.MBeanRegistrationException JavaDoc;
23 import javax.management.MBeanServerConnection JavaDoc;
24 import javax.management.MBeanServerNotification JavaDoc;
25 import javax.management.NotCompliantMBeanException JavaDoc;
26 import javax.management.Notification JavaDoc;
27 import javax.management.NotificationBroadcasterSupport JavaDoc;
28 import javax.management.NotificationEmitter JavaDoc;
29 import javax.management.NotificationFilter JavaDoc;
30 import javax.management.NotificationFilterSupport JavaDoc;
31 import javax.management.NotificationListener JavaDoc;
32 import javax.management.ObjectInstance JavaDoc;
33 import javax.management.ObjectName JavaDoc;
34 import javax.management.QueryExp JavaDoc;
35 import javax.management.ReflectionException JavaDoc;
36
37 import javax.management.remote.JMXAuthenticator JavaDoc;
38 import javax.management.remote.JMXConnectionNotification JavaDoc;
39 import javax.management.remote.JMXConnector JavaDoc;
40 import javax.management.remote.JMXConnectorFactory JavaDoc;
41 import javax.management.remote.JMXServiceURL JavaDoc;
42 import javax.management.remote.NotificationResult JavaDoc;
43 import javax.management.remote.TargetedNotification JavaDoc;
44 import javax.management.remote.JMXServerErrorException JavaDoc;
45
46 import java.lang.ref.WeakReference JavaDoc;
47
48 import java.lang.reflect.Constructor JavaDoc;
49 import java.lang.reflect.InvocationTargetException JavaDoc;
50
51 // Util
52
import java.util.Arrays JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.Collections JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.Properties JavaDoc;
58 import java.util.Set JavaDoc;
59 import java.util.WeakHashMap JavaDoc;
60
61 // IO
62
import java.io.ByteArrayInputStream JavaDoc;
63 import java.io.IOException JavaDoc;
64 import java.io.InputStream JavaDoc;
65 import java.io.InvalidObjectException JavaDoc;
66 import java.io.ObjectInputStream JavaDoc;
67 import java.io.ObjectStreamClass JavaDoc;
68 import java.io.Serializable JavaDoc;
69 import java.io.WriteAbortedException JavaDoc;
70 import java.io.NotSerializableException JavaDoc;
71
72 // Net
73
import java.net.MalformedURLException JavaDoc;
74
75 // RMI
76
import java.rmi.MarshalledObject JavaDoc;
77 import java.rmi.NoSuchObjectException JavaDoc;
78 import java.rmi.MarshalException JavaDoc;
79 import java.rmi.UnmarshalException JavaDoc;
80 import java.rmi.ServerException JavaDoc;
81 import java.rmi.server.RemoteObject JavaDoc;
82 import java.rmi.server.RemoteRef JavaDoc;
83
84 //IIOP RMI
85
import javax.rmi.PortableRemoteObject JavaDoc;
86 import javax.rmi.CORBA.Stub JavaDoc;
87 import org.omg.CORBA.portable.Delegate JavaDoc;
88
89 // JNDI
90
import javax.naming.InitialContext JavaDoc;
91 import javax.naming.NamingException JavaDoc;
92
93 import com.sun.jmx.remote.internal.ClientNotifForwarder;
94 import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
95 import com.sun.jmx.remote.internal.ClientListenerInfo;
96 import com.sun.jmx.remote.internal.ProxyInputStream;
97 import com.sun.jmx.remote.internal.ProxyRef;
98 import com.sun.jmx.remote.util.ClassLogger;
99 import com.sun.jmx.remote.util.EnvHelp;
100
101 // SECURITY
102
import java.security.AccessController JavaDoc;
103 import java.security.PrivilegedAction JavaDoc;
104 import java.security.PrivilegedExceptionAction JavaDoc;
105 import java.security.ProtectionDomain JavaDoc;
106 import javax.security.auth.Subject JavaDoc;
107
108 /**
109  * <p>A connection to a remote RMI connector. Usually, such
110  * connections are made using {@link
111  * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}.
112  * However, specialized applications can use this class directly, for
113  * example with an {@link RMIServer} stub obtained without going
114  * through JNDI.</p>
115  *
116  * @since 1.5
117  * @since.unbundled 1.0
118  */

119 public class RMIConnector implements JMXConnector JavaDoc, Serializable JavaDoc {
120
121     private static final ClassLogger logger =
122     new ClassLogger("javax.management.remote.rmi", "RMIConnector");
123
124     private static final long serialVersionUID = 817323035842634473L;
125
126     private RMIConnector(RMIServer JavaDoc rmiServer, JMXServiceURL JavaDoc address,
127                          Map JavaDoc environment) {
128         if (rmiServer == null && address == null) throw new
129           IllegalArgumentException JavaDoc("rmiServer and jmxServiceURL both null");
130
131     initTransients();
132
133     this.rmiServer = rmiServer;
134         this.jmxServiceURL = address;
135         if (environment == null) {
136             this.env = Collections.EMPTY_MAP;
137         } else {
138             EnvHelp.checkAttributes(environment);
139             this.env = Collections.unmodifiableMap(environment);
140         }
141     }
142
143     /**
144      * <p>Constructs an <code>RMIConnector</code> that will connect
145      * the RMI connector server with the given address.</p>
146      *
147      * <p>The address can refer directly to the connector server,
148      * using one of the following syntaxes:</p>
149      *
150      * <pre>
151      * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
152      * service:jmx:iiop://<em>[host[:port]]</em>/ior/<em>encoded-IOR</em>
153      * </pre>
154      *
155      * <p>(Here, the square brackets <code>[]</code> are not part of the
156      * address but indicate that the host and port are optional.)</p>
157      *
158      * <p>The address can instead indicate where to find an RMI stub
159      * through JNDI, using one of the following syntaxes:</p>
160      *
161      * <pre>
162      * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
163      * service:jmx:iiop://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
164      * </pre>
165      *
166      * <p>An implementation may also recognize additional address
167      * syntaxes, for example:</p>
168      *
169      * <pre>
170      * service:jmx:iiop://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
171      * </pre>
172      *
173      * @param url the address of the RMI connector server.
174      *
175      * @param environment additional attributes specifying how to make
176      * the connection. For JNDI-based addresses, these attributes can
177      * usefully include JNDI attributes recognized by {@link
178      * InitialContext#InitialContext(Hashtable) InitialContext}. This
179      * parameter can be null, which is equivalent to an empty Map.
180      *
181      * @exception IllegalArgumentException if <code>url</code>
182      * is null.
183      */

184     public RMIConnector(JMXServiceURL JavaDoc url, Map JavaDoc<String JavaDoc,?> environment) {
185         this(null, url, environment);
186     }
187
188     /**
189      * <p>Constructs an <code>RMIConnector</code> using the given RMI stub.
190      *
191      * @param rmiServer an RMI stub representing the RMI connector server.
192      * @param environment additional attributes specifying how to make
193      * the connection. This parameter can be null, which is
194      * equivalent to an empty Map.
195      *
196      * @exception IllegalArgumentException if <code>rmiServer</code>
197      * is null.
198      */

199     public RMIConnector(RMIServer JavaDoc rmiServer, Map JavaDoc<String JavaDoc,?> environment) {
200         this(rmiServer, null, environment);
201     }
202
203     /**
204      * <p>Returns a string representation of this object. In general,
205      * the <code>toString</code> method returns a string that
206      * "textually represents" this object. The result should be a
207      * concise but informative representation that is easy for a
208      * person to read.</p>
209      *
210      * @return a String representation of this object.
211      **/

212     public String JavaDoc toString() {
213         final StringBuffer JavaDoc b = new StringBuffer JavaDoc(this.getClass().getName());
214         b.append(":");
215         if (rmiServer != null) {
216             b.append(" rmiServer=").append(rmiServer.toString());
217         }
218         if (jmxServiceURL != null) {
219             if (rmiServer!=null) b.append(",");
220             b.append(" jmxServiceURL=").append(jmxServiceURL.toString());
221         }
222         return b.toString();
223     }
224
225     //--------------------------------------------------------------------
226
// implements JMXConnector interface
227
//--------------------------------------------------------------------
228
public void connect() throws IOException JavaDoc {
229     connect(null);
230     }
231
232     public synchronized void connect(Map JavaDoc<String JavaDoc,?> environment)
233         throws IOException JavaDoc {
234     final boolean tracing = logger.traceOn();
235     String JavaDoc idstr = (tracing?"["+this.toString()+"]":null);
236
237         if (terminated) {
238         logger.trace("connect",idstr + " already closed.");
239         throw new IOException JavaDoc("Connector closed");
240     }
241         if (connected) {
242         logger.trace("connect",idstr + " already connected.");
243             return;
244     }
245
246         try {
247         if (tracing) logger.trace("connect",idstr + " connecting...");
248
249             final Map JavaDoc usemap =
250         new HashMap JavaDoc((this.env==null)?Collections.EMPTY_MAP:this.env);
251
252             if (environment != null) {
253         EnvHelp.checkAttributes(environment);
254                 usemap.putAll(environment);
255             }
256
257             // Get RMIServer stub from directory or URL encoding if needed.
258
if (tracing) logger.trace("connect",idstr + " finding stub...");
259             RMIServer JavaDoc stub = (rmiServer!=null)?rmiServer:
260                 findRMIServer(jmxServiceURL, usemap);
261
262             // Connect IIOP Stub if needed.
263
if (tracing) logger.trace("connect",idstr + " connecting stub...");
264             stub = connectStub(stub,usemap);
265         idstr = (tracing?"["+this.toString()+"]":null);
266
267             // Calling newClient on the RMIServer stub.
268
if (tracing)
269         logger.trace("connect",idstr + " getting connection...");
270         Object JavaDoc credentials = usemap.get(CREDENTIALS);
271             connection = getConnection(stub, credentials);
272
273             // Always use one of:
274
// ClassLoader provided in Map at connect time,
275
// or contextClassLoader at connect time.
276
if (tracing)
277         logger.trace("connect",idstr + " getting class loader...");
278             defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap);
279
280             usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
281                        defaultClassLoader);
282
283         rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap);
284
285         env = usemap;
286         final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
287         communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);
288
289             connected = true;
290
291         // The connectionId variable is used in doStart(), when
292
// reconnecting, to identify the "old" connection.
293
//
294
connectionId = getConnectionId();
295
296         Notification JavaDoc connectedNotif =
297         new JMXConnectionNotification JavaDoc(JMXConnectionNotification.OPENED,
298                           this,
299                           connectionId,
300                           clientNotifID++,
301                           "Successful connection",
302                           null);
303         sendNotification(connectedNotif);
304
305         if (tracing) logger.trace("connect",idstr + " done...");
306         } catch (IOException JavaDoc e) {
307         if (tracing)
308         logger.trace("connect",idstr + " failed to connect: " + e);
309             throw e;
310         } catch (RuntimeException JavaDoc e) {
311         if (tracing)
312         logger.trace("connect",idstr + " failed to connect: " + e);
313             throw e;
314         } catch (NamingException JavaDoc e) {
315             final String JavaDoc msg = "Failed to retrieve RMIServer stub: " + e;
316         if (tracing) logger.trace("connect",idstr + " " + msg);
317             throw (IOException JavaDoc) EnvHelp.initCause(new IOException JavaDoc(msg),e);
318         }
319     }
320
321     public synchronized String JavaDoc getConnectionId() throws IOException JavaDoc {
322         if (terminated || !connected) {
323         if (logger.traceOn())
324         logger.trace("getConnectionId","["+this.toString()+
325               "] not connected.");
326
327             throw new IOException JavaDoc("Not connected");
328     }
329
330     // we do a remote call to have an IOException if the connection is broken.
331
// see the bug 4939578
332
return connection.getConnectionId();
333     }
334
335     public synchronized MBeanServerConnection JavaDoc getMBeanServerConnection()
336         throws IOException JavaDoc {
337     return getMBeanServerConnection(null);
338     }
339
340     public synchronized MBeanServerConnection JavaDoc
341     getMBeanServerConnection(Subject JavaDoc delegationSubject)
342         throws IOException JavaDoc {
343
344         if (terminated) {
345         if (logger.traceOn())
346         logger.trace("getMBeanServerConnection","[" + this.toString() +
347               "] already closed.");
348         throw new IOException JavaDoc("Connection closed");
349     } else if (!connected) {
350         if (logger.traceOn())
351         logger.trace("getMBeanServerConnection","[" + this.toString() +
352               "] is not connected.");
353         throw new IOException JavaDoc("Not connected");
354     }
355
356     MBeanServerConnection JavaDoc mbsc =
357         (MBeanServerConnection JavaDoc) rmbscMap.get(delegationSubject);
358     if (mbsc != null)
359         return mbsc;
360
361     mbsc = new RemoteMBeanServerConnection(delegationSubject);
362     rmbscMap.put(delegationSubject, mbsc);
363     return mbsc;
364     }
365
366     public void
367     addConnectionNotificationListener(NotificationListener JavaDoc listener,
368                       NotificationFilter JavaDoc filter,
369                       Object JavaDoc handback) {
370     if (listener == null)
371         throw new NullPointerException JavaDoc("listener");
372     connectionBroadcaster.addNotificationListener(listener, filter,
373                               handback);
374     }
375
376     public void
377     removeConnectionNotificationListener(NotificationListener JavaDoc listener)
378         throws ListenerNotFoundException JavaDoc {
379     if (listener == null)
380         throw new NullPointerException JavaDoc("listener");
381     connectionBroadcaster.removeNotificationListener(listener);
382     }
383
384     public void
385     removeConnectionNotificationListener(NotificationListener JavaDoc listener,
386                          NotificationFilter JavaDoc filter,
387                          Object JavaDoc handback)
388         throws ListenerNotFoundException JavaDoc {
389     if (listener == null)
390         throw new NullPointerException JavaDoc("listener");
391     connectionBroadcaster.removeNotificationListener(listener, filter,
392                              handback);
393     }
394
395     private void sendNotification(Notification JavaDoc n) {
396     connectionBroadcaster.sendNotification(n);
397     }
398
399     public synchronized void close() throws IOException JavaDoc {
400     close(false);
401     }
402
403     // allows to do close after setting the flag "terminated" to true.
404
// It is necessary to avoid a deadlock, see 6296324
405
private synchronized void close(boolean intern) throws IOException JavaDoc {
406     final boolean tracing = logger.traceOn();
407     final boolean debug = logger.debugOn();
408     final String JavaDoc idstr = (tracing?"["+this.toString()+"]":null);
409
410     if (!intern) {
411         // Return if already cleanly closed.
412
//
413
if (terminated) {
414         if (closeException == null) {
415             if (tracing) logger.trace("close",idstr + " already closed.");
416             return;
417         }
418         } else {
419         terminated = true;
420         }
421     }
422
423     if (closeException != null && tracing) {
424         // Already closed, but not cleanly. Attempt again.
425
//
426
if (tracing) {
427         logger.trace("close",idstr + " had failed: " + closeException);
428         logger.trace("close",idstr + " attempting to close again.");
429         }
430     }
431
432         String JavaDoc savedConnectionId = null;
433     if (connected) {
434         savedConnectionId = connectionId;
435     }
436
437     closeException = null;
438
439     if (tracing) logger.trace("close",idstr + " closing.");
440
441     if (communicatorAdmin != null) {
442         communicatorAdmin.terminate();
443     }
444
445     if (rmiNotifClient != null) {
446         try {
447         rmiNotifClient.terminate();
448         if (tracing) logger.trace("close",idstr +
449                     " RMI Notification client terminated.");
450         } catch (RuntimeException JavaDoc x) {
451         closeException = x;
452         if (tracing) logger.trace("close",idstr +
453              " Failed to terminate RMI Notification client: " + x);
454         if (debug) logger.debug("close",x);
455         }
456     }
457
458     if (connection != null) {
459         try {
460         connection.close();
461         if (tracing) logger.trace("close",idstr + " closed.");
462         } catch (NoSuchObjectException JavaDoc nse) {
463         // OK, the server maybe closed itself.
464
} catch (IOException JavaDoc e) {
465         closeException = e;
466         if (tracing) logger.trace("close",idstr +
467                       " Failed to close RMIServer: " + e);
468         if (debug) logger.debug("close",e);
469         }
470     }
471
472     // Clean up MBeanServerConnection table
473
//
474
rmbscMap.clear();
475
476     /* Send notification of closure. We don't do this if the user
477      * never called connect() on the connector, because there's no
478      * connection id in that case. */

479
480     if (savedConnectionId != null) {
481         Notification JavaDoc closedNotif =
482         new JMXConnectionNotification JavaDoc(JMXConnectionNotification.CLOSED,
483                           this,
484                           savedConnectionId,
485                           clientNotifID++,
486                           "Client has been closed",
487                           null);
488         sendNotification(closedNotif);
489     }
490
491     // throw exception if needed
492
//
493
if (closeException != null) {
494         if (tracing) logger.trace("close",idstr + " failed to close: " +
495                    closeException);
496         if (closeException instanceof IOException JavaDoc)
497         throw (IOException JavaDoc) closeException;
498         if (closeException instanceof RuntimeException JavaDoc)
499         throw (RuntimeException JavaDoc) closeException;
500         final IOException JavaDoc x =
501         new IOException JavaDoc("Failed to close: " + closeException);
502         throw (IOException JavaDoc) EnvHelp.initCause(x,closeException);
503     }
504     }
505
506     // added for re-connection
507
private Integer JavaDoc addListenerWithSubject(ObjectName JavaDoc name,
508                        MarshalledObject JavaDoc filter,
509                        Subject JavaDoc delegationSubject,
510                        boolean reconnect)
511     throws InstanceNotFoundException JavaDoc, IOException JavaDoc {
512         
513     final boolean debug = logger.debugOn();
514     if (debug)
515         logger.debug("addListenerWithSubject",
516              "(ObjectName,MarshalledObject,Subject)");
517         
518     final ObjectName JavaDoc[] names = new ObjectName JavaDoc[] {name};
519     final MarshalledObject JavaDoc[] filters = new MarshalledObject JavaDoc[] {filter};
520     final Subject JavaDoc[] delegationSubjects = new Subject JavaDoc[] {
521         delegationSubject
522     };
523
524     final Integer JavaDoc[] listenerIDs =
525         addListenersWithSubjects(names,filters,delegationSubjects,
526                       reconnect);
527         
528     if (debug) logger.debug("addListenerWithSubject","listenerID="
529                 + listenerIDs[0]);
530     return listenerIDs[0];
531     }
532
533     // added for re-connection
534
private Integer JavaDoc[] addListenersWithSubjects(ObjectName JavaDoc[] names,
535                  MarshalledObject JavaDoc[] filters,
536                  Subject JavaDoc[] delegationSubjects,
537                  boolean reconnect)
538     throws InstanceNotFoundException JavaDoc, IOException JavaDoc {
539
540     final boolean debug = logger.debugOn();
541     if (debug)
542     logger.debug("addListenersWithSubjects",
543              "(ObjectName[],MarshalledObject[],Subject[])");
544
545     final ClassLoader JavaDoc old = pushDefaultClassLoader();
546     Integer JavaDoc[] listenerIDs = null;
547
548     try {
549         listenerIDs = connection.addNotificationListeners(names,
550                                   filters,
551                               delegationSubjects);
552     } catch (NoSuchObjectException JavaDoc noe) {
553         // maybe reconnect
554
if (reconnect) {
555         communicatorAdmin.gotIOException(noe);
556         
557         listenerIDs = connection.addNotificationListeners(names,
558                                filters,
559                                delegationSubjects);
560         } else {
561         throw noe;
562         }
563     } catch (IOException JavaDoc ioe) {
564         // send a failed notif if necessary
565
communicatorAdmin.gotIOException(ioe);
566     } finally {
567         popDefaultClassLoader(old);
568     }
569         
570     if (debug) logger.debug("addListenersWithSubjects","registered "
571                 + listenerIDs.length + " listener(s)");
572     return listenerIDs;
573     }
574
575     //--------------------------------------------------------------------
576
// Implementation of MBeanServerConnection
577
//--------------------------------------------------------------------
578
private class RemoteMBeanServerConnection
579         implements MBeanServerConnection JavaDoc {
580
581     private Subject JavaDoc delegationSubject;
582
583     public RemoteMBeanServerConnection() {
584         this(null);
585     }
586
587     public RemoteMBeanServerConnection(Subject JavaDoc delegationSubject) {
588         this.delegationSubject = delegationSubject;
589     }
590
591         public ObjectInstance JavaDoc createMBean(String JavaDoc className,
592                                           ObjectName JavaDoc name)
593                 throws ReflectionException JavaDoc,
594                        InstanceAlreadyExistsException JavaDoc,
595                        MBeanRegistrationException JavaDoc,
596                        MBeanException JavaDoc,
597                        NotCompliantMBeanException JavaDoc,
598                        IOException JavaDoc {
599         if (logger.debugOn())
600         logger.debug("createMBean(String,ObjectName)",
601                  "className=" + className + ", name=" +
602                  name);
603
604             final ClassLoader JavaDoc old = pushDefaultClassLoader();
605             try {
606                 return connection.createMBean(className,
607                          name,
608                          delegationSubject);
609         } catch (IOException JavaDoc ioe) {
610         communicatorAdmin.gotIOException(ioe);
611
612                 return connection.createMBean(className,
613                          name,
614                          delegationSubject);
615             } finally {
616                 popDefaultClassLoader(old);
617             }
618         }
619
620         public ObjectInstance JavaDoc createMBean(String JavaDoc className,
621                                           ObjectName JavaDoc name,
622                                           ObjectName JavaDoc loaderName)
623             throws ReflectionException JavaDoc,
624                        InstanceAlreadyExistsException JavaDoc,
625                        MBeanRegistrationException JavaDoc,
626                        MBeanException JavaDoc,
627                        NotCompliantMBeanException JavaDoc,
628                        InstanceNotFoundException JavaDoc,
629                        IOException JavaDoc {
630
631         if (logger.debugOn())
632         logger.debug("createMBean(String,ObjectName,ObjectName)",
633               "className=" + className + ", name="
634               + name + ", loaderName="
635               + loaderName + ")");
636
637             final ClassLoader JavaDoc old = pushDefaultClassLoader();
638             try {
639                 return connection.createMBean(className,
640                          name,
641                          loaderName,
642                          delegationSubject);
643
644         } catch (IOException JavaDoc ioe) {
645         communicatorAdmin.gotIOException(ioe);
646
647                 return connection.createMBean(className,
648                          name,
649                          loaderName,
650                          delegationSubject);
651
652             } finally {
653                 popDefaultClassLoader(old);
654             }
655         }
656
657         public ObjectInstance JavaDoc createMBean(String JavaDoc className,
658                                           ObjectName JavaDoc name,
659                                           Object JavaDoc params[],
660                                           String JavaDoc signature[])
661                 throws ReflectionException JavaDoc,
662                        InstanceAlreadyExistsException JavaDoc,
663                        MBeanRegistrationException JavaDoc,
664                        MBeanException JavaDoc,
665                        NotCompliantMBeanException JavaDoc,
666                        IOException JavaDoc {
667         if (logger.debugOn())
668            logger.debug("createMBean(String,ObjectName,Object[],String[])",
669               "className=" + className + ", name="
670               + name + ", params="
671               + objects(params) + ", signature="
672               + strings(signature));
673
674             final MarshalledObject JavaDoc sParams = new MarshalledObject JavaDoc(params);
675             final ClassLoader JavaDoc old = pushDefaultClassLoader();
676             try {
677                 return connection.createMBean(className,
678                          name,
679                          sParams,
680                          signature,
681                          delegationSubject);
682         } catch (IOException JavaDoc ioe) {
683         communicatorAdmin.gotIOException(ioe);
684
685                 return connection.createMBean(className,
686                          name,
687                          sParams,
688                          signature,
689                          delegationSubject);
690             } finally {
691                 popDefaultClassLoader(old);
692             }
693         }
694
695         public ObjectInstance JavaDoc createMBean(String JavaDoc className,
696                                           ObjectName JavaDoc name,
697                                           ObjectName JavaDoc loaderName,
698                                           Object JavaDoc params[],
699                                           String JavaDoc signature[])
700                 throws ReflectionException JavaDoc,
701                        InstanceAlreadyExistsException JavaDoc,
702                        MBeanRegistrationException JavaDoc,
703                        MBeanException JavaDoc,
704                        NotCompliantMBeanException JavaDoc,
705                        InstanceNotFoundException JavaDoc,
706                        IOException JavaDoc {
707         if (logger.debugOn()) logger.debug(
708         "createMBean(String,ObjectName,ObjectName,Object[],String[])",
709         "className=" + className + ", name=" + name + ", loaderName="
710         + loaderName + ", params=" + objects(params)
711         + ", signature=" + strings(signature));
712
713             final MarshalledObject JavaDoc sParams = new MarshalledObject JavaDoc(params);
714             final ClassLoader JavaDoc old = pushDefaultClassLoader();
715             try {
716                 return connection.createMBean(className,
717                          name,
718                          loaderName,
719                          sParams,
720                          signature,
721                          delegationSubject);
722         } catch (IOException JavaDoc ioe) {
723         communicatorAdmin.gotIOException(ioe);
724
725                 return connection.createMBean(className,
726                          name,
727                          loaderName,
728                          sParams,
729                          signature,
730                          delegationSubject);
731             } finally {
732                 popDefaultClassLoader(old);
733             }
734         }
735
736         public void unregisterMBean(ObjectName JavaDoc name)
737                 throws InstanceNotFoundException JavaDoc,
738                        MBeanRegistrationException JavaDoc,
739                        IOException JavaDoc {
740         if (logger.debugOn())
741         logger.debug("unregisterMBean", "name=" + name);
742
743             final ClassLoader JavaDoc old = pushDefaultClassLoader();
744             try {
745                 connection.unregisterMBean(name, delegationSubject);
746         } catch (IOException JavaDoc ioe) {
747         communicatorAdmin.gotIOException(ioe);
748
749                 connection.unregisterMBean(name, delegationSubject);
750             } finally {
751                 popDefaultClassLoader(old);
752             }
753         }
754
755         public ObjectInstance JavaDoc getObjectInstance(ObjectName JavaDoc name)
756                 throws InstanceNotFoundException JavaDoc,
757                        IOException JavaDoc {
758         if (logger.debugOn())
759         logger.debug("getObjectInstance", "name=" + name);
760
761             final ClassLoader JavaDoc old = pushDefaultClassLoader();
762             try {
763                 return connection.getObjectInstance(name, delegationSubject);
764         } catch (IOException JavaDoc ioe) {
765         communicatorAdmin.gotIOException(ioe);
766
767                 return connection.getObjectInstance(name, delegationSubject);
768             } finally {
769                 popDefaultClassLoader(old);
770             }
771         }
772
773         public Set JavaDoc queryMBeans(ObjectName JavaDoc name,
774                                QueryExp JavaDoc query)
775             throws IOException JavaDoc {
776         if (logger.debugOn()) logger.debug("queryMBeans",
777                    "name=" + name + ", query=" + query);
778
779             final MarshalledObject JavaDoc sQuery = new MarshalledObject JavaDoc(query);
780             final ClassLoader JavaDoc old = pushDefaultClassLoader();
781             try {
782                 return connection.queryMBeans(name, sQuery, delegationSubject);
783         } catch (IOException JavaDoc ioe) {
784         communicatorAdmin.gotIOException(ioe);
785
786                 return connection.queryMBeans(name, sQuery, delegationSubject);
787             } finally {
788                 popDefaultClassLoader(old);
789             }
790         }
791
792         public Set JavaDoc queryNames(ObjectName JavaDoc name,
793                               QueryExp JavaDoc query)
794                 throws IOException JavaDoc {
795         if (logger.debugOn()) logger.debug("queryNames",
796                    "name=" + name + ", query=" + query);
797
798             final MarshalledObject JavaDoc sQuery = new MarshalledObject JavaDoc(query);
799             final ClassLoader JavaDoc old = pushDefaultClassLoader();
800             try {
801                 return connection.queryNames(name, sQuery, delegationSubject);
802         } catch (IOException JavaDoc ioe) {
803         communicatorAdmin.gotIOException(ioe);
804
805                 return connection.queryNames(name, sQuery, delegationSubject);
806             } finally {
807                 popDefaultClassLoader(old);
808             }
809         }
810
811         public boolean isRegistered(ObjectName JavaDoc name)
812                 throws IOException JavaDoc {
813         if (logger.debugOn())
814         logger.debug("isRegistered", "name=" + name);
815
816             final ClassLoader JavaDoc old = pushDefaultClassLoader();
817             try {
818                 return connection.isRegistered(name, delegationSubject);
819         } catch (IOException JavaDoc ioe) {
820         communicatorAdmin.gotIOException(ioe);
821
822                 return connection.isRegistered(name, delegationSubject);
823             } finally {
824                 popDefaultClassLoader(old);
825             }
826         }
827
828         public Integer JavaDoc getMBeanCount()
829                 throws IOException JavaDoc {
830         if (logger.debugOn()) logger.debug("getMBeanCount", "");
831
832             final ClassLoader JavaDoc old = pushDefaultClassLoader();
833             try {
834                 return connection.getMBeanCount(delegationSubject);
835         } catch (IOException JavaDoc ioe) {
836         communicatorAdmin.gotIOException(ioe);
837
838                 return connection.getMBeanCount(delegationSubject);
839             } finally {
840                 popDefaultClassLoader(old);
841             }
842         }
843
844         public Object JavaDoc getAttribute(ObjectName JavaDoc name,
845                                    String JavaDoc attribute)
846                 throws MBeanException JavaDoc,
847                        AttributeNotFoundException JavaDoc,
848                        InstanceNotFoundException JavaDoc,
849                        ReflectionException JavaDoc,
850                        IOException JavaDoc {
851         if (logger.debugOn()) logger.debug("getAttribute",
852                    "name=" + name + ", attribute="
853                    + attribute);
854
855             final ClassLoader JavaDoc old = pushDefaultClassLoader();
856             try {
857                 return connection.getAttribute(name,
858                           attribute,
859                           delegationSubject);
860         } catch (IOException JavaDoc ioe) {
861         communicatorAdmin.gotIOException(ioe);
862
863                 return connection.getAttribute(name,
864                           attribute,
865                           delegationSubject);
866             } finally {
867                 popDefaultClassLoader(old);
868             }
869         }
870
871         public AttributeList JavaDoc getAttributes(ObjectName JavaDoc name,
872                                            String JavaDoc[] attributes)
873                 throws InstanceNotFoundException JavaDoc,
874                        ReflectionException JavaDoc,
875                        IOException JavaDoc {
876         if (logger.debugOn()) logger.debug("getAttributes",
877                    "name=" + name + ", attributes="
878                    + strings(attributes));
879
880             final ClassLoader JavaDoc old = pushDefaultClassLoader();
881             try {
882                 return connection.getAttributes(name,
883                            attributes,
884                            delegationSubject);
885
886         } catch (IOException JavaDoc ioe) {
887         communicatorAdmin.gotIOException(ioe);
888
889                 return connection.getAttributes(name,
890                            attributes,
891                            delegationSubject);
892             } finally {
893                 popDefaultClassLoader(old);
894             }
895         }
896
897
898         public void setAttribute(ObjectName JavaDoc name,
899                                  Attribute JavaDoc attribute)
900             throws InstanceNotFoundException JavaDoc,
901                    AttributeNotFoundException JavaDoc,
902                    InvalidAttributeValueException JavaDoc,
903                    MBeanException JavaDoc,
904                    ReflectionException JavaDoc,
905                    IOException JavaDoc {
906
907         if (logger.debugOn()) logger.debug("setAttribute",
908                    "name=" + name + ", attribute="
909                    + attribute);
910
911             final MarshalledObject JavaDoc sAttribute =
912         new MarshalledObject JavaDoc(attribute);
913             final ClassLoader JavaDoc old = pushDefaultClassLoader();
914             try {
915                 connection.setAttribute(name, sAttribute, delegationSubject);
916         } catch (IOException JavaDoc ioe) {
917         communicatorAdmin.gotIOException(ioe);
918
919                 connection.setAttribute(name, sAttribute, delegationSubject);
920             } finally {
921                 popDefaultClassLoader(old);
922             }
923         }
924
925         public AttributeList JavaDoc setAttributes(ObjectName JavaDoc name,
926                                            AttributeList JavaDoc attributes)
927             throws InstanceNotFoundException JavaDoc,
928                    ReflectionException JavaDoc,
929                    IOException JavaDoc {
930
931         if (logger.debugOn()) logger.debug("setAttributes",
932                    "name=" + name + ", attributes="
933                    + attributes);
934
935             final MarshalledObject JavaDoc sAttributes =
936                 new MarshalledObject JavaDoc(attributes);
937             final ClassLoader JavaDoc old = pushDefaultClassLoader();
938             try {
939                 return connection.setAttributes(name,
940                            sAttributes,
941                            delegationSubject);
942         } catch (IOException JavaDoc ioe) {
943         communicatorAdmin.gotIOException(ioe);
944
945                 return connection.setAttributes(name,
946                            sAttributes,
947                            delegationSubject);
948             } finally {
949                 popDefaultClassLoader(old);
950             }
951         }
952
953
954         public Object JavaDoc invoke(ObjectName JavaDoc name,
955                              String JavaDoc operationName,
956                              Object JavaDoc params[],
957                              String JavaDoc signature[])
958                 throws InstanceNotFoundException JavaDoc,
959                        MBeanException JavaDoc,
960                        ReflectionException JavaDoc,
961                        IOException JavaDoc {
962
963         if (logger.debugOn()) logger.debug("invoke",
964                    "name=" + name
965                    + ", operationName=" + operationName
966                    + ", params=" + objects(params)
967                    + ", signature=" + strings(signature));
968
969             final MarshalledObject JavaDoc sParams = new MarshalledObject JavaDoc(params);
970             final ClassLoader JavaDoc old = pushDefaultClassLoader();
971             try {
972                 return connection.invoke(name,
973                     operationName,
974                     sParams,
975                                         signature,
976                     delegationSubject);
977         } catch (IOException JavaDoc ioe) {
978         communicatorAdmin.gotIOException(ioe);
979
980                 return connection.invoke(name,
981                     operationName,
982                     sParams,
983                                         signature,
984                     delegationSubject);
985             } finally {
986                 popDefaultClassLoader(old);
987             }
988         }
989
990
991         public String JavaDoc getDefaultDomain()
992                 throws IOException JavaDoc {
993         if (logger.debugOn()) logger.debug("getDefaultDomain", "");
994
995             final ClassLoader JavaDoc old = pushDefaultClassLoader();
996             try {
997         return connection.getDefaultDomain(delegationSubject);
998         } catch (IOException JavaDoc ioe) {
999         communicatorAdmin.gotIOException(ioe);
1000
1001        return connection.getDefaultDomain(delegationSubject);
1002            } finally {
1003                popDefaultClassLoader(old);
1004            }
1005        }
1006
1007        public String JavaDoc[] getDomains() throws IOException JavaDoc {
1008        if (logger.debugOn()) logger.debug("getDomains", "");
1009
1010            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1011            try {
1012                return connection.getDomains(delegationSubject);
1013        } catch (IOException JavaDoc ioe) {
1014        communicatorAdmin.gotIOException(ioe);
1015
1016                return connection.getDomains(delegationSubject);
1017            } finally {
1018                popDefaultClassLoader(old);
1019            }
1020        }
1021
1022        public MBeanInfo JavaDoc getMBeanInfo(ObjectName JavaDoc name)
1023                throws InstanceNotFoundException JavaDoc,
1024                       IntrospectionException JavaDoc,
1025                       ReflectionException JavaDoc,
1026                       IOException JavaDoc {
1027
1028        if (logger.debugOn()) logger.debug("getMBeanInfo", "name=" + name);
1029            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1030            try {
1031                return connection.getMBeanInfo(name, delegationSubject);
1032        } catch (IOException JavaDoc ioe) {
1033        communicatorAdmin.gotIOException(ioe);
1034
1035                return connection.getMBeanInfo(name, delegationSubject);
1036            } finally {
1037                popDefaultClassLoader(old);
1038            }
1039        }
1040
1041
1042        public boolean isInstanceOf(ObjectName JavaDoc name,
1043                                    String JavaDoc className)
1044                throws InstanceNotFoundException JavaDoc,
1045                       IOException JavaDoc {
1046        if (logger.debugOn())
1047        logger.debug("isInstanceOf", "name=" + name +
1048                 ", className=" + className);
1049
1050            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1051            try {
1052                return connection.isInstanceOf(name,
1053                          className,
1054                          delegationSubject);
1055        } catch (IOException JavaDoc ioe) {
1056        communicatorAdmin.gotIOException(ioe);
1057
1058                return connection.isInstanceOf(name,
1059                          className,
1060                          delegationSubject);
1061            } finally {
1062                popDefaultClassLoader(old);
1063            }
1064        }
1065
1066        public void addNotificationListener(ObjectName JavaDoc name,
1067                                            ObjectName JavaDoc listener,
1068                                            NotificationFilter JavaDoc filter,
1069                                            Object JavaDoc handback)
1070                throws InstanceNotFoundException JavaDoc,
1071                       IOException JavaDoc {
1072
1073        if (logger.debugOn())
1074        logger.debug("addNotificationListener" +
1075               "(ObjectName,ObjectName,NotificationFilter,Object)",
1076               "name=" + name + ", listener=" + listener
1077               + ", filter=" + filter + ", handback=" + handback);
1078
1079            final MarshalledObject JavaDoc sFilter = new MarshalledObject JavaDoc(filter);
1080            final MarshalledObject JavaDoc sHandback = new MarshalledObject JavaDoc(handback);
1081            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1082            try {
1083                connection.addNotificationListener(name,
1084                          listener,
1085                          sFilter,
1086                          sHandback,
1087                          delegationSubject);
1088        } catch (IOException JavaDoc ioe) {
1089        communicatorAdmin.gotIOException(ioe);
1090
1091                connection.addNotificationListener(name,
1092                          listener,
1093                          sFilter,
1094                          sHandback,
1095                          delegationSubject);
1096            } finally {
1097                popDefaultClassLoader(old);
1098            }
1099        }
1100
1101        public void removeNotificationListener(ObjectName JavaDoc name,
1102                                               ObjectName JavaDoc listener)
1103                throws InstanceNotFoundException JavaDoc,
1104                       ListenerNotFoundException JavaDoc,
1105                       IOException JavaDoc {
1106
1107        if (logger.debugOn()) logger.debug("removeNotificationListener" +
1108                   "(ObjectName,ObjectName)",
1109                   "name=" + name
1110                   + ", listener=" + listener);
1111
1112            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1113            try {
1114                connection.removeNotificationListener(name,
1115                             listener,
1116                             delegationSubject);
1117        } catch (IOException JavaDoc ioe) {
1118        communicatorAdmin.gotIOException(ioe);
1119
1120                connection.removeNotificationListener(name,
1121                             listener,
1122                             delegationSubject);
1123            } finally {
1124                popDefaultClassLoader(old);
1125            }
1126        }
1127
1128        public void removeNotificationListener(ObjectName JavaDoc name,
1129                                               ObjectName JavaDoc listener,
1130                                               NotificationFilter JavaDoc filter,
1131                                               Object JavaDoc handback)
1132                throws InstanceNotFoundException JavaDoc,
1133                       ListenerNotFoundException JavaDoc,
1134                       IOException JavaDoc {
1135        if (logger.debugOn())
1136        logger.debug("removeNotificationListener" +
1137              "(ObjectName,ObjectName,NotificationFilter,Object)",
1138              "name=" + name
1139              + ", listener=" + listener
1140              + ", filter=" + filter
1141              + ", handback=" + handback);
1142
1143            final MarshalledObject JavaDoc sFilter = new MarshalledObject JavaDoc(filter);
1144            final MarshalledObject JavaDoc sHandback = new MarshalledObject JavaDoc(handback);
1145            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1146            try {
1147                connection.removeNotificationListener(name,
1148                             listener,
1149                                                     sFilter,
1150                             sHandback,
1151                             delegationSubject);
1152        } catch (IOException JavaDoc ioe) {
1153        communicatorAdmin.gotIOException(ioe);
1154
1155                connection.removeNotificationListener(name,
1156                             listener,
1157                                                     sFilter,
1158                             sHandback,
1159                             delegationSubject);
1160            } finally {
1161                popDefaultClassLoader(old);
1162            }
1163        }
1164
1165        // Specific Notification Handle ----------------------------------
1166

1167        public void addNotificationListener(ObjectName JavaDoc name,
1168                                            NotificationListener JavaDoc listener,
1169                                            NotificationFilter JavaDoc filter,
1170                                            Object JavaDoc handback)
1171                throws InstanceNotFoundException JavaDoc,
1172                       IOException JavaDoc {
1173
1174        final boolean debug = logger.debugOn();
1175        if (debug)
1176        logger.debug("addNotificationListener" +
1177                 "(ObjectName,NotificationListener,"+
1178                 "NotificationFilter,Object)",
1179                 "name=" + name
1180                 + ", listener=" + listener
1181                 + ", filter=" + filter
1182                 + ", handback=" + handback);
1183
1184        final Integer JavaDoc listenerID =
1185        addListenerWithSubject(name, new MarshalledObject JavaDoc(filter),
1186                       delegationSubject,true);
1187        rmiNotifClient.addNotificationListener(listenerID, name, listener,
1188                           filter, handback,
1189                           delegationSubject);
1190    }
1191
1192        public void removeNotificationListener(ObjectName JavaDoc name,
1193                                               NotificationListener JavaDoc listener)
1194                throws InstanceNotFoundException JavaDoc,
1195                       ListenerNotFoundException JavaDoc,
1196                       IOException JavaDoc {
1197        final boolean debug = logger.debugOn();
1198
1199        if (debug) logger.debug("removeNotificationListener"+
1200                 "(ObjectName,NotificationListener)",
1201                 "name=" + name
1202                 + ", listener=" + listener);
1203
1204            final Integer JavaDoc[] ret =
1205                rmiNotifClient.removeNotificationListener(name, listener);
1206
1207        if (debug) logger.debug("removeNotificationListener",
1208                 "listenerIDs=" + objects(ret));
1209
1210            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1211
1212            try {
1213                connection.removeNotificationListeners(name,
1214                               ret,
1215                               delegationSubject);
1216        } catch (IOException JavaDoc ioe) {
1217        communicatorAdmin.gotIOException(ioe);
1218
1219                connection.removeNotificationListeners(name,
1220                               ret,
1221                               delegationSubject);
1222            } finally {
1223                popDefaultClassLoader(old);
1224            }
1225
1226        }
1227
1228        public void removeNotificationListener(ObjectName JavaDoc name,
1229                                           NotificationListener JavaDoc listener,
1230                                           NotificationFilter JavaDoc filter,
1231                                           Object JavaDoc handback)
1232            throws InstanceNotFoundException JavaDoc,
1233                   ListenerNotFoundException JavaDoc,
1234                   IOException JavaDoc {
1235        final boolean debug = logger.debugOn();
1236
1237        if (debug)
1238        logger.debug("removeNotificationListener"+
1239              "(ObjectName,NotificationListener,"+
1240              "NotificationFilter,Object)",
1241              "name=" + name
1242              + ", listener=" + listener
1243              + ", filter=" + filter
1244              + ", handback=" + handback);
1245
1246            final Integer JavaDoc ret =
1247                rmiNotifClient.removeNotificationListener(name, listener,
1248                                                         filter, handback);
1249
1250        if (debug) logger.debug("removeNotificationListener",
1251                 "listenerID=" + ret);
1252
1253            final ClassLoader JavaDoc old = pushDefaultClassLoader();
1254            try {
1255                connection.removeNotificationListeners(name,
1256                               new Integer JavaDoc[] {ret},
1257                               delegationSubject);
1258        } catch (IOException JavaDoc ioe) {
1259        communicatorAdmin.gotIOException(ioe);
1260
1261                connection.removeNotificationListeners(name,
1262                               new Integer JavaDoc[] {ret},
1263                               delegationSubject);
1264            } finally {
1265                popDefaultClassLoader(old);
1266            }
1267
1268        }
1269    }
1270
1271    //--------------------------------------------------------------------
1272
private class RMINotifClient extends ClientNotifForwarder {
1273    public RMINotifClient(ClassLoader JavaDoc cl, Map JavaDoc env) {
1274        super(cl, env);
1275    }
1276
1277    protected NotificationResult JavaDoc fetchNotifs(long clientSequenceNumber,
1278                         int maxNotifications,
1279                         long timeout)
1280        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1281        IOException JavaDoc org;
1282
1283        while (true) { // used for a successful re-connection
1284
try {
1285            return connection.fetchNotifications(clientSequenceNumber,
1286                             maxNotifications,
1287                             timeout);
1288        } catch (IOException JavaDoc ioe) {
1289            org = ioe;
1290            
1291            // inform of IOException
1292
try {
1293            communicatorAdmin.gotIOException(ioe);
1294            
1295            // The connection should be re-established.
1296
continue;
1297            } catch (IOException JavaDoc ee) {
1298            // No more fetch, the Exception will be re-thrown.
1299
break;
1300            } // never reached
1301
} // never reached
1302
}
1303
1304        // specially treating for an UnmarshalException
1305
if (org instanceof UnmarshalException JavaDoc) {
1306        UnmarshalException JavaDoc ume = (UnmarshalException JavaDoc)org;
1307        
1308        if (ume.detail instanceof ClassNotFoundException JavaDoc)
1309            throw (ClassNotFoundException JavaDoc) ume.detail;
1310        
1311        /* In Sun's RMI implementation, if a method return
1312           contains an unserializable object, then we get
1313           UnmarshalException wrapping WriteAbortedException
1314           wrapping NotSerializableException. In that case we
1315           extract the NotSerializableException so that our
1316           caller can realize it should try to skip past the
1317           notification that presumably caused it. It's not
1318           certain that every other RMI implementation will
1319           generate this exact exception sequence. If not, we
1320           will not detect that the problem is due to an
1321           unserializable object, and we will stop trying to
1322           receive notifications from the server. It's not
1323           clear we can do much better. */

1324        if (ume.detail instanceof WriteAbortedException JavaDoc) {
1325            WriteAbortedException JavaDoc wae =
1326            (WriteAbortedException JavaDoc) ume.detail;
1327            if (wae.detail instanceof IOException JavaDoc)
1328            throw (IOException JavaDoc) wae.detail;
1329        }
1330        } else if (org instanceof MarshalException JavaDoc) {
1331        // IIOP will throw MarshalException wrapping a NotSerializableException
1332
// when a server fails to serialize a response.
1333
MarshalException JavaDoc me = (MarshalException JavaDoc)org;
1334        if (me.detail instanceof NotSerializableException JavaDoc) {
1335            throw (NotSerializableException JavaDoc)me.detail;
1336        }
1337        }
1338
1339        // Not serialization problem, simply re-throw the orginal exception
1340
throw org;
1341    }
1342
1343    protected Integer JavaDoc addListenerForMBeanRemovedNotif()
1344        throws IOException JavaDoc, InstanceNotFoundException JavaDoc {
1345        MarshalledObject JavaDoc sFilter = null;
1346        NotificationFilterSupport JavaDoc clientFilter =
1347        new NotificationFilterSupport JavaDoc();
1348        clientFilter.enableType(
1349        MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
1350        sFilter = new MarshalledObject JavaDoc(clientFilter);
1351
1352        Integer JavaDoc[] listenerIDs;
1353        final ObjectName JavaDoc[] names = new ObjectName JavaDoc[] {delegateName};
1354        final MarshalledObject JavaDoc[] filters =
1355        new MarshalledObject JavaDoc[] {sFilter};
1356        final Subject JavaDoc[] subjects = new Subject JavaDoc[] {null};
1357        try {
1358        listenerIDs =
1359            connection.addNotificationListeners(names,
1360                            filters,
1361                            subjects);
1362
1363        } catch (IOException JavaDoc ioe) {
1364        communicatorAdmin.gotIOException(ioe);
1365
1366        listenerIDs =
1367            connection.addNotificationListeners(names,
1368                            filters,
1369                            subjects);
1370        }
1371        return listenerIDs[0];
1372    }
1373
1374    protected void removeListenerForMBeanRemovedNotif(Integer JavaDoc id)
1375        throws IOException JavaDoc, InstanceNotFoundException JavaDoc,
1376               ListenerNotFoundException JavaDoc {
1377        try {
1378        connection.removeNotificationListeners(delegateName,
1379                               new Integer JavaDoc[] {id},
1380                               null);
1381        } catch (IOException JavaDoc ioe) {
1382        communicatorAdmin.gotIOException(ioe);
1383
1384        connection.removeNotificationListeners(delegateName,
1385                               new Integer JavaDoc[] {id},
1386                               null);
1387        }
1388
1389    }
1390
1391    protected void lostNotifs(String JavaDoc message, long number) {
1392        final String JavaDoc notifType = JMXConnectionNotification.NOTIFS_LOST;
1393
1394        final JMXConnectionNotification JavaDoc n =
1395        new JMXConnectionNotification JavaDoc(notifType,
1396                          RMIConnector.this,
1397                          connectionId,
1398                          clientNotifCounter++,
1399                          message,
1400                          new Long JavaDoc(number));
1401        sendNotification(n);
1402    }
1403    }
1404
1405    private class RMIClientCommunicatorAdmin extends ClientCommunicatorAdmin {
1406    public RMIClientCommunicatorAdmin(long period) {
1407        super(period);
1408    }
1409
1410    public void gotIOException (IOException JavaDoc ioe) throws IOException JavaDoc {
1411        if (ioe instanceof NoSuchObjectException JavaDoc) {
1412        // need to restart
1413
super.gotIOException(ioe);
1414
1415        return;
1416        }
1417
1418        // check if the connection is broken
1419
try {
1420        connection.getDefaultDomain(null);
1421        } catch (IOException JavaDoc ioexc) {
1422        boolean toClose = false;
1423
1424        synchronized(this) {
1425            if (!terminated) {
1426            terminated = true;
1427            
1428            toClose = true;
1429            }
1430        }
1431
1432        if (toClose) {
1433            // we should close the connection,
1434
// but send a failed notif at first
1435
final Notification JavaDoc failedNotif =
1436            new JMXConnectionNotification JavaDoc(
1437                JMXConnectionNotification.FAILED,
1438                this,
1439                connectionId,
1440                clientNotifID++,
1441                "Failed to communicate with the server: "+ioe.toString(),
1442                ioe);
1443            
1444            sendNotification(failedNotif);
1445
1446            try {
1447            close(true);
1448            } catch (Exception JavaDoc e) {
1449            // OK.
1450
// We are closing
1451
}
1452        }
1453        }
1454
1455        // forward the exception
1456
if (ioe instanceof ServerException JavaDoc) {
1457        /* Need to unwrap the exception.
1458           Some user-thrown exception at server side will be wrapped by
1459           rmi into a ServerException.
1460           For example, a RMIConnnectorServer will wrap a
1461           ClassNotFoundException into a UnmarshalException, and rmi
1462           will throw a ServerException at client side which wraps this
1463           UnmarshalException.
1464           No failed notif here.
1465        */

1466        Throwable JavaDoc tt = ((ServerException JavaDoc)ioe).detail;
1467
1468        if (tt instanceof IOException JavaDoc) {
1469            throw (IOException JavaDoc)tt;
1470        } else if (tt instanceof RuntimeException JavaDoc) {
1471            throw (RuntimeException JavaDoc)tt;
1472        }
1473        }
1474
1475        throw ioe;
1476    }
1477
1478    public void reconnectNotificationListeners(ClientListenerInfo[] old) throws IOException JavaDoc {
1479        final int len = old.length;
1480        int i;
1481
1482        ClientListenerInfo[] clis = new ClientListenerInfo[len];
1483
1484        final Subject JavaDoc[] subjects = new Subject JavaDoc[len];
1485        final ObjectName JavaDoc[] names = new ObjectName JavaDoc[len];
1486        final NotificationListener JavaDoc[] listeners = new NotificationListener JavaDoc[len];
1487        final NotificationFilter JavaDoc[] filters = new NotificationFilter JavaDoc[len];
1488        final MarshalledObject JavaDoc[] mFilters = new MarshalledObject JavaDoc[len];
1489        final Object JavaDoc[] handbacks = new Object JavaDoc[len];
1490       
1491        for (i=0;i<len;i++) {
1492        subjects[i] = old[i].getDelegationSubject();
1493        names[i] = old[i].getObjectName();
1494        listeners[i] = old[i].getListener();
1495        filters[i] = old[i].getNotificationFilter();
1496        mFilters[i] = new MarshalledObject JavaDoc(filters[i]);
1497        handbacks[i] = old[i].getHandback();
1498        }
1499
1500        try {
1501        Integer JavaDoc[] ids = addListenersWithSubjects(names,mFilters,subjects,false);
1502
1503        for (i=0;i<len;i++) {
1504            clis[i] = new ClientListenerInfo(ids[i],
1505                             names[i],
1506                             listeners[i],
1507                             filters[i],
1508                             handbacks[i],
1509                             subjects[i]);
1510        }
1511
1512        rmiNotifClient.postReconnection(clis);
1513
1514        return;
1515        } catch (InstanceNotFoundException JavaDoc infe) {
1516        // OK, we will do one by one
1517
}
1518
1519        int j = 0;
1520        for (i=0;i<len;i++) {
1521        try {
1522            Integer JavaDoc id = addListenerWithSubject(names[i],
1523                       new MarshalledObject JavaDoc(filters[i]),
1524                       subjects[i],
1525                       false);
1526
1527            clis[j++] = new ClientListenerInfo(id,
1528                               names[i],
1529                               listeners[i],
1530                               filters[i],
1531                               handbacks[i],
1532                               subjects[i]);
1533        } catch (InstanceNotFoundException JavaDoc infe) {
1534            logger.warning("reconnectNotificationListeners",
1535                   "Can't reconnect listener for " +
1536                   names[i]);
1537        }
1538        }
1539
1540        if (j != len) {
1541        ClientListenerInfo[] tmp = clis;
1542        clis = new ClientListenerInfo[j];
1543        System.arraycopy(tmp, 0, clis, 0, j);
1544        }
1545
1546        rmiNotifClient.postReconnection(clis);
1547    }
1548
1549    protected void checkConnection() throws IOException JavaDoc {
1550        if (logger.debugOn())
1551        logger.debug("RMIClientCommunicatorAdmin-checkConnection",
1552                 "Calling the method getDefaultDomain.");
1553
1554        connection.getDefaultDomain(null);
1555    }
1556
1557    protected void doStart() throws IOException JavaDoc {
1558            // Get RMIServer stub from directory or URL encoding if needed.
1559
RMIServer JavaDoc stub = null;
1560        try {
1561            stub = (rmiServer!=null)?rmiServer:
1562            findRMIServer(jmxServiceURL, env);
1563        } catch (NamingException JavaDoc ne) {
1564        throw new IOException JavaDoc("Failed to get a RMI stub: "+ne);
1565        }
1566
1567            // Connect IIOP Stub if needed.
1568
stub = connectStub(stub,env);
1569
1570            // Calling newClient on the RMIServer stub.
1571
Object JavaDoc credentials = env.get(CREDENTIALS);
1572            connection = stub.newClient(credentials);
1573
1574        // notif issues
1575
final ClientListenerInfo[] old = rmiNotifClient.preReconnection();
1576
1577        reconnectNotificationListeners(old);
1578
1579        connectionId = getConnectionId();
1580
1581        Notification JavaDoc reconnectedNotif =
1582        new JMXConnectionNotification JavaDoc(JMXConnectionNotification.OPENED,
1583                          this,
1584                          connectionId,
1585                          clientNotifID++,
1586                          "Reconnected to server",
1587                          null);
1588        sendNotification(reconnectedNotif);
1589
1590    }
1591
1592    protected void doStop() {
1593        try {
1594        close();
1595        } catch (IOException JavaDoc ioe) {
1596        logger.warning("RMIClientCommunicatorAdmin-doStop",
1597                   "Failed to call the method close():" + ioe);
1598        logger.debug("RMIClientCommunicatorAdmin-doStop",ioe);
1599        }
1600    }
1601    }
1602
1603    //--------------------------------------------------------------------
1604
// Private stuff - Serialization
1605
//--------------------------------------------------------------------
1606
/**
1607     * <p>In order to be usable, an IIOP stub must be connected to an ORB.
1608     * The stub is automagically connected to the ORB if:
1609     * <ul>
1610     * <li> It was returned by the COS naming</li>
1611     * <li> Its server counterpart has been registered in COS naming
1612     * through JNDI.</li>
1613     * </ul>
1614     * Otherwise, it is not connected. A stub which is deserialized
1615     * from Jini is not connected. A stub which is obtained from a
1616     * non registered RMIIIOPServerImpl is not a connected.<br>
1617     * A stub which is not connected can't be serialized, and thus
1618     * can't be registered in Jini. A stub which is not connected can't
1619     * be used to invoke methods on the server.
1620     * <p>
1621     * In order to palliate this, this method will connect the
1622     * given stub if it is not yet connected. If the given
1623     * <var>RMIServer</var> is not an instance of
1624     * {@link javax.rmi.CORBA.Stub javax.rmi.CORBA.Stub}, then the
1625     * method do nothing and simply returns that stub. Otherwise,
1626     * this method will attempt to connect the stub to an ORB as
1627     * follows:
1628     * <ul>
1629     * <p>This method looks in the provided <var>environment</var> for
1630     * the "java.naming.corba.orb" property. If it is found, the
1631     * referenced object (an {@link org.omg.CORBA.ORB ORB}) is used to
1632     * connect the stub. Otherwise, a new org.omg.CORBA.ORB is created
1633     * by calling {@link
1634     * org.omg.CORBA.ORB#init(String[], Properties)
1635     * org.omg.CORBA.ORB.init((String[])null,(Properties)null)}
1636     * <p>The new created ORB is kept in a static
1637     * {@link WeakReference} and can be reused for connecting other
1638     * stubs. However, no reference is ever kept on the ORB provided
1639     * in the <var>environment</var> map, if any.
1640     * </ul>
1641     * @param rmiServer A RMI Server Stub.
1642     * @param environment An environment map, possibly containing an ORB.
1643     * @return the given stub.
1644     * @exception IllegalArgumentException if the
1645     * <tt>java.naming.corba.orb</tt> property is specified and
1646     * does not point to an {@link org.omg.CORBA.ORB ORB}.
1647     * @exception IOException if the connection to the ORB failed.
1648     **/

1649    static RMIServer JavaDoc connectStub(RMIServer JavaDoc rmiServer,
1650                                 Map JavaDoc environment)
1651        throws IOException JavaDoc {
1652        if (rmiServer instanceof javax.rmi.CORBA.Stub JavaDoc) {
1653            javax.rmi.CORBA.Stub JavaDoc stub = (javax.rmi.CORBA.Stub JavaDoc) rmiServer;
1654            try {
1655                stub._orb();
1656            } catch (org.omg.CORBA.BAD_OPERATION JavaDoc x) {
1657                stub.connect(resolveOrb(environment));
1658            }
1659        }
1660        return rmiServer;
1661    }
1662
1663    /**
1664     * Get the ORB specified by <var>environment</var>, or create a
1665     * new one.
1666     * <p>This method looks in the provided <var>environment</var> for
1667     * the "java.naming.corba.orb" property. If it is found, the
1668     * referenced object (an {@link org.omg.CORBA.ORB ORB}) is
1669     * returned. Otherwise, a new org.omg.CORBA.ORB is created
1670     * by calling {@link
1671     * org.omg.CORBA.ORB#init(String[], java.util.Properties)
1672     * org.omg.CORBA.ORB.init((String[])null,(Properties)null)}
1673     * <p>The new created ORB is kept in a static
1674     * {@link WeakReference} and can be reused for connecting other
1675     * stubs. However, no reference is ever kept on the ORB provided
1676     * in the <var>environment</var> map, if any.
1677     * @param environment An environment map, possibly containing an ORB.
1678     * @return An ORB.
1679     * @exception IllegalArgumentException if the
1680     * <tt>java.naming.corba.orb</tt> property is specified and
1681     * does not point to an {@link org.omg.CORBA.ORB ORB}.
1682     * @exception IOException if the ORB initialization failed.
1683     **/

1684    static org.omg.CORBA.ORB JavaDoc resolveOrb(Map JavaDoc environment)
1685        throws IOException JavaDoc {
1686        if (environment != null) {
1687            final Object JavaDoc orb = environment.get(EnvHelp.DEFAULT_ORB);
1688            if (orb != null && !(orb instanceof org.omg.CORBA.ORB JavaDoc))
1689                throw new IllegalArgumentException JavaDoc(EnvHelp.DEFAULT_ORB +
1690                          " must be an instance of org.omg.CORBA.ORB.");
1691            if (orb != null) return (org.omg.CORBA.ORB JavaDoc)orb;
1692        }
1693        final Object JavaDoc orb =
1694            (RMIConnector.orb==null)?null:RMIConnector.orb.get();
1695        if (orb != null) return (org.omg.CORBA.ORB JavaDoc)orb;
1696
1697        final org.omg.CORBA.ORB JavaDoc newOrb =
1698            org.omg.CORBA.ORB.init((String JavaDoc[])null, (Properties JavaDoc)null);
1699        RMIConnector.orb = new WeakReference JavaDoc(newOrb);
1700        return newOrb;
1701    }
1702
1703    /**
1704     * Read RMIConnector fields from an {@link java.io.ObjectInputStream
1705     * ObjectInputStream}.
1706     * Calls <code>s.defaultReadObject()</code> and then initializes
1707     * all transient variables that need initializing.
1708     * @param s The ObjectInputStream to read from.
1709     * @exception InvalidObjectException if none of <var>rmiServer</var> stub
1710     * or <var>jmxServiceURL</var> are set.
1711     * @see #RMIConnector(JMXServiceURL,Map)
1712     * @see #RMIConnector(RMIServer,Map)
1713     **/

1714    private void readObject(java.io.ObjectInputStream JavaDoc s)
1715        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1716        s.defaultReadObject();
1717
1718        if (rmiServer == null && jmxServiceURL == null) throw new
1719          InvalidObjectException JavaDoc("rmiServer and jmxServiceURL both null");
1720
1721    initTransients();
1722    }
1723
1724    /**
1725     * Writes the RMIConnector fields to an {@link java.io.ObjectOutputStream
1726     * ObjectOutputStream}.
1727     * <p>Connects the underlying RMIServer stub to an ORB, if needed,
1728     * before serializing it. This is done using the environment
1729     * map that was provided to the constructor, if any, and as documented
1730     * in {@link javax.management.remote.rmi}.</p>
1731     * <p>This method then calls <code>s.defaultWriteObject()</code>.
1732     * Usually, <var>rmiServer</var> is null if this object
1733     * was constructed with a JMXServiceURL, and <var>jmxServiceURL</var>
1734     * is null if this object is constructed with a RMIServer stub.
1735     * <p>Note that the environment Map is not serialized, since the objects
1736     * it contains are assumed to be contextual and relevant only
1737     * with respect to the local environment (class loader, ORB, etc...).</p>
1738     * <p>After an RMIConnector is deserialized, it is assumed that the
1739     * user will call {@link #connect(Map)}, providing a new Map that
1740     * can contain values which are contextually relevant to the new
1741     * local environment.</p>
1742     * <p>Since connection to the ORB is needed prior to serializing, and
1743     * since the ORB to connect to is one of those contextual parameters,
1744     * it is not recommended to re-serialize a just de-serialized object -
1745     * as the de-serialized object has no map. Thus, when an RMIConnector
1746     * object is needed for serialization or transmission to a remote
1747     * application, it is recommended to obtain a new RMIConnector stub
1748     * by calling {@link RMIConnectorServer#toJMXConnector(Map)}.</p>
1749     * @param s The ObjectOutputStream to write to.
1750     * @exception InvalidObjectException if none of <var>rmiServer</var> stub
1751     * or <var>jmxServiceURL</var> are set.
1752     * @see #RMIConnector(JMXServiceURL,Map)
1753     * @see #RMIConnector(RMIServer,Map)
1754     **/

1755    private void writeObject(java.io.ObjectOutputStream JavaDoc s)
1756        throws IOException JavaDoc {
1757        if (rmiServer == null && jmxServiceURL == null) throw new
1758          InvalidObjectException JavaDoc("rmiServer and jmxServiceURL both null.");
1759        connectStub(this.rmiServer,env);
1760        s.defaultWriteObject();
1761    }
1762
1763    // Initialization of transient variables.
1764
private void initTransients() {
1765    rmbscMap = new WeakHashMap JavaDoc();
1766        connected = false;
1767        terminated = false;
1768
1769    connectionBroadcaster = new NotificationBroadcasterSupport JavaDoc();
1770    }
1771
1772    //--------------------------------------------------------------------
1773
// Private stuff - RMIServer creation
1774
//--------------------------------------------------------------------
1775

1776    private RMIServer JavaDoc findRMIServer(JMXServiceURL JavaDoc directoryURL,
1777                    Map JavaDoc environment)
1778        throws NamingException JavaDoc, IOException JavaDoc {
1779        final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true);
1780        if (isIiop) {
1781            // Make sure java.naming.corba.orb is in the Map.
1782
environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment));
1783        }
1784
1785    String JavaDoc path = directoryURL.getURLPath();
1786    if (path.startsWith("/jndi/"))
1787        return findRMIServerJNDI(path.substring(6), environment, isIiop);
1788    else if (path.startsWith("/stub/"))
1789        return findRMIServerJRMP(path.substring(6), environment, isIiop);
1790    else if (path.startsWith("/ior/"))
1791        return findRMIServerIIOP(path.substring(5), environment, isIiop);
1792    else {
1793        final String JavaDoc msg = "URL path must begin with /jndi/ or /stub/ " +
1794        "or /ior/: " + path;
1795        throw new MalformedURLException JavaDoc(msg);
1796    }
1797    }
1798
1799    /**
1800     * Lookup the RMIServer stub in a directory.
1801     * @param jndiURL A JNDI URL indicating the location of the Stub
1802     * (see {@link javax.management.remote.rmi}), e.g.:
1803     * <ul><li><tt>rmi://registry-host:port/rmi-stub-name</tt></li>
1804     * <li>or <tt>iiop://cosnaming-host:port/iiop-stub-name</tt></li>
1805     * <li>or <tt>ldap://ldap-host:port/java-container-dn</tt></li>
1806     * </ul>
1807     * @param env the environment Map passed to the connector.
1808     * @param isIiop true if the stub is expected to be an IIOP stub.
1809     * @return The retrieved RMIServer stub.
1810     * @exception NamingException if the stub couldn't be found.
1811     **/

1812    private RMIServer JavaDoc findRMIServerJNDI(String JavaDoc jndiURL, Map JavaDoc env, boolean isIiop)
1813    throws NamingException JavaDoc {
1814
1815    InitialContext JavaDoc ctx = new InitialContext JavaDoc(EnvHelp.mapToHashtable(env));
1816
1817    Object JavaDoc objref = ctx.lookup(jndiURL);
1818    ctx.close();
1819
1820    if (isIiop)
1821        return narrowIIOPServer(objref);
1822    else
1823        return narrowJRMPServer(objref);
1824    }
1825
1826    private static RMIServer JavaDoc narrowJRMPServer(Object JavaDoc objref) {
1827
1828        return (RMIServer JavaDoc) objref;
1829    }
1830
1831    private static RMIServer JavaDoc narrowIIOPServer(Object JavaDoc objref) {
1832        try {
1833            return (RMIServer JavaDoc)
1834                PortableRemoteObject.narrow(objref, RMIServer JavaDoc.class);
1835        } catch (ClassCastException JavaDoc e) {
1836            if (logger.traceOn())
1837        logger.trace("narrowIIOPServer","Failed to narrow objref=" +
1838              objref + ": " + e);
1839        if (logger.debugOn()) logger.debug("narrowIIOPServer",e);
1840            return null;
1841        }
1842    }
1843
1844    private RMIServer JavaDoc findRMIServerIIOP(String JavaDoc ior, Map JavaDoc env, boolean isIiop) {
1845    // could forbid "rmi:" URL here -- but do we need to?
1846
final org.omg.CORBA.ORB JavaDoc orb = (org.omg.CORBA.ORB JavaDoc)
1847        env.get(EnvHelp.DEFAULT_ORB);
1848    final Object JavaDoc stub = orb.string_to_object(ior);
1849    return (RMIServer JavaDoc) PortableRemoteObject.narrow(stub, RMIServer JavaDoc.class);
1850    }
1851
1852    private RMIServer JavaDoc findRMIServerJRMP(String JavaDoc base64, Map JavaDoc env, boolean isIiop)
1853    throws IOException JavaDoc {
1854    // could forbid "iiop:" URL here -- but do we need to?
1855
final byte[] serialized;
1856    try {
1857        serialized = base64ToByteArray(base64);
1858    } catch (IllegalArgumentException JavaDoc e) {
1859        throw new MalformedURLException JavaDoc("Bad BASE64 encoding: " +
1860                        e.getMessage());
1861    }
1862    final ByteArrayInputStream JavaDoc bin = new ByteArrayInputStream JavaDoc(serialized);
1863
1864    final ClassLoader JavaDoc loader = EnvHelp.resolveClientClassLoader(env);
1865    final ObjectInputStream JavaDoc oin =
1866        (loader == null) ?
1867        new ObjectInputStream JavaDoc(bin) :
1868        new ObjectInputStreamWithLoader(bin, loader);
1869    final Object JavaDoc stub;
1870    try {
1871        stub = oin.readObject();
1872    } catch (ClassNotFoundException JavaDoc e) {
1873        throw new MalformedURLException JavaDoc("Class not found: " + e);
1874    }
1875    return (RMIServer JavaDoc) PortableRemoteObject.narrow(stub, RMIServer JavaDoc.class);
1876    }
1877
1878    private static final class ObjectInputStreamWithLoader
1879        extends ObjectInputStream JavaDoc {
1880    ObjectInputStreamWithLoader(InputStream JavaDoc in, ClassLoader JavaDoc cl)
1881        throws IOException JavaDoc {
1882        super(in);
1883        this.loader = cl;
1884    }
1885
1886    protected Class JavaDoc resolveClass(ObjectStreamClass JavaDoc classDesc)
1887        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1888        return Class.forName(classDesc.getName(), false, loader);
1889    }
1890
1891    private final ClassLoader JavaDoc loader;
1892    }
1893
1894    /*
1895       The following section of code avoids a class loading problem
1896       with RMI. The problem is that an RMI stub, when deserializing
1897       a remote method return value or exception, will first of all
1898       consult the first non-bootstrap class loader it finds in the
1899       call stack. This can lead to behavior that is not portable
1900       between implementations of the JMX Remote API. Notably, an
1901       implementation on J2SE 1.4 will find the RMI stub's loader on
1902       the stack. But in J2SE 5, this stub is loaded by the
1903       bootstrap loader, so RMI will find the loader of the user code
1904       that called an MBeanServerConnection method.
1905
1906       To avoid this problem, we take advantage of what the RMI stub
1907       is doing internally. Each remote call will end up calling
1908       ref.invoke(...), where ref is the RemoteRef parameter given to
1909       the RMI stub's constructor. It is within this call that the
1910       deserialization will happen. So we fabricate our own RemoteRef
1911       that delegates everything to the "real" one but that is loaded
1912       by a class loader that knows no other classes. The class
1913       loader NoCallStackClassLoader does this: the RemoteRef is an
1914       instance of the class named by proxyRefClassName, which is
1915       fabricated by the class loader using byte code that is defined
1916       by the string below.
1917
1918       The call stack when the deserialization happens is thus this:
1919       MBeanServerConnection.getAttribute (or whatever)
1920       -> RMIConnectionImpl_Stub.getAttribute
1921          -> ProxyRef.invoke(...getAttribute...)
1922             -> UnicastRef.invoke(...getAttribute...)
1923                -> internal RMI stuff
1924
1925       Here UnicastRef is the RemoteRef created when the stub was
1926       deserialized (which is of some RMI internal class). It and the
1927       "internal RMI stuff" are loaded by the bootstrap loader, so are
1928       transparent to the stack search. The first non-bootstrap
1929       loader found is our ProxyRefLoader, as required.
1930
1931       In a future version of this code as integrated into J2SE 5,
1932       this workaround could be replaced by direct access to the
1933       internals of RMI. For now, we use the same code base for J2SE
1934       and for the standalone Reference Implementation.
1935
1936       The byte code below encodes the following class, compiled using
1937       J2SE 1.4.2 with the -g:none option.
1938
1939    package com.sun.jmx.remote.internal;
1940
1941    import java.lang.reflect.Method;
1942    import java.rmi.Remote;
1943    import java.rmi.server.RemoteRef;
1944    import com.sun.jmx.remote.internal.ProxyRef;
1945
1946    public class PRef extends ProxyRef {
1947        public PRef(RemoteRef ref) {
1948        super(ref);
1949        }
1950
1951        public Object invoke(Remote obj, Method method,
1952                 Object[] params, long opnum)
1953            throws Exception {
1954        return ref.invoke(obj, method, params, opnum);
1955        }
1956    }
1957     */

1958
1959    private static final String JavaDoc rmiConnectionImplStubClassName =
1960    RMIConnection JavaDoc.class.getName() + "Impl_Stub";
1961    private static final Class JavaDoc rmiConnectionImplStubClass;
1962    private static final String JavaDoc pRefClassName =
1963    "com.sun.jmx.remote.internal.PRef";
1964    private static final Constructor JavaDoc proxyRefConstructor;
1965    static {
1966    final String JavaDoc pRefByteCodeString =
1967        "\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+
1968        "\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/RemoteRef;"+
1969        ")V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/reflec"+
1970        "t/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12Exception"+
1971        "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/"+
1972        "sun/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/internal/Pr"+
1973        "oxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rmi/serve"+
1974        "r/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5\0\0\0\0"+
1975        "\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"+
1976        "\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"+
1977        "\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";
1978    final byte[] pRefByteCode =
1979        NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
1980    PrivilegedExceptionAction JavaDoc action = new PrivilegedExceptionAction JavaDoc() {
1981        public Object JavaDoc run() throws Exception JavaDoc {
1982        Class JavaDoc thisClass = RMIConnector JavaDoc.class;
1983        ClassLoader JavaDoc thisLoader = thisClass.getClassLoader();
1984        ProtectionDomain JavaDoc thisProtectionDomain =
1985            thisClass.getProtectionDomain();
1986        String JavaDoc[] otherClassNames = {ProxyRef.class.getName()};
1987        ClassLoader JavaDoc cl =
1988            new NoCallStackClassLoader JavaDoc(pRefClassName,
1989                           pRefByteCode,
1990                           otherClassNames,
1991                           thisLoader,
1992                           thisProtectionDomain);
1993        Class JavaDoc c = cl.loadClass(pRefClassName);
1994        return c.getConstructor(new Class JavaDoc[] {RemoteRef JavaDoc.class});
1995        }
1996    };
1997
1998    Class JavaDoc stubClass;
1999    Constructor JavaDoc constr;
2000    try {
2001        stubClass = Class.forName(rmiConnectionImplStubClassName);
2002        constr = (Constructor JavaDoc) AccessController.doPrivileged(action);
2003    } catch (Exception JavaDoc e) {
2004        logger.error("<clinit>",
2005             "Failed to initialize proxy reference consructor "+
2006             "for " + rmiConnectionImplStubClassName + ": " + e);
2007        logger.debug("<clinit>",e);
2008        stubClass = null;
2009        constr = null;
2010    }
2011    rmiConnectionImplStubClass = stubClass;
2012    proxyRefConstructor = constr;
2013    }
2014
2015    private static RMIConnection JavaDoc shadowJrmpStub(RemoteObject JavaDoc stub)
2016        throws InstantiationException JavaDoc, IllegalAccessException JavaDoc,
2017           InvocationTargetException JavaDoc, ClassNotFoundException JavaDoc,
2018           NoSuchMethodException JavaDoc {
2019    RemoteRef JavaDoc ref = stub.getRef();
2020    RemoteRef JavaDoc proxyRef = (RemoteRef JavaDoc)
2021        proxyRefConstructor.newInstance(new Object JavaDoc[] {ref});
2022    final Class JavaDoc[] constrTypes = {RemoteRef JavaDoc.class};
2023    final Constructor JavaDoc rmiConnectionImplStubConstructor =
2024        rmiConnectionImplStubClass.getConstructor(constrTypes);
2025    Object JavaDoc[] args = {proxyRef};
2026    RMIConnection JavaDoc proxyStub = (RMIConnection JavaDoc)
2027        rmiConnectionImplStubConstructor.newInstance(args);
2028    return proxyStub;
2029    }
2030
2031    /*
2032       The following code performs a similar trick for RMI/IIOP to the
2033       one described above for RMI/JRMP. Unlike JRMP, though, we
2034       can't easily insert an object between the RMIConnection stub
2035       and the RMI/IIOP deserialization code, as explained below.
2036
2037       A method in an RMI/IIOP stub does the following. It makes an
2038       org.omg.CORBA_2_3.portable.OutputStream for each request, and
2039       writes the parameters to it. Then it calls
2040       _invoke(OutputStream) which it inherits from CORBA's
2041       ObjectImpl. That returns an
2042       org.omg.CORBA_2_3.portable.InputStream. The return value is
2043       read from this InputStream. So the stack during
2044       deserialization looks like this:
2045
2046       MBeanServerConnection.getAttribute (or whatever)
2047       -> _RMIConnection_Stub.getAttribute
2048          -> Util.readAny (a CORBA method)
2049             -> InputStream.read_any
2050                -> internal CORBA stuff
2051
2052       What we would have *liked* to have done would be the same thing
2053       as for RMI/JRMP. We create a "ProxyDelegate" that is an
2054       org.omg.CORBA.portable.Delegate that simply forwards every
2055       operation to the real original Delegate from the RMIConnection
2056       stub, except that the InputStream returned by _invoke is
2057       wrapped by a "ProxyInputStream" that is loaded by our
2058       NoCallStackClassLoader.
2059
2060       Unfortunately, this doesn't work, at least with Sun's J2SE
2061       1.4.2, because the CORBA code is not designed to allow you to
2062       change Delegates arbitrarily. You get a ClassCastException
2063       from code that expects the Delegate to implement an internal
2064       interface.
2065
2066       So instead we do the following. We create a subclass of the
2067       stub that overrides the _invoke method so as to wrap the
2068       returned InputStream in a ProxyInputStream. We create a
2069       subclass of ProxyInputStream using the NoCallStackClassLoader
2070       and override its read_any and read_value(Class) methods.
2071       (These are the only methods called during deserialization of
2072       MBeanServerConnection return values.) We extract the Delegate
2073       from the original stub and insert it into our subclass stub,
2074       and away we go. The state of a stub consists solely of its
2075       Delegate.
2076
2077       We also need to catch ApplicationException, which will encode
2078       any exceptions declared in the throws clause of the called
2079       method. Its InputStream needs to be wrapped in a
2080       ProxyInputSteam too.
2081
2082       We override _releaseReply in the stub subclass so that it
2083       replaces a ProxyInputStream argument with the original
2084       InputStream. This avoids problems if the implementation of
2085       _releaseReply ends up casting this InputStream to an
2086       implementation-specific interface (which in Sun's J2SE 5 it
2087       does).
2088
2089       It is not strictly necessary for the stub subclass to be loaded
2090       by a NoCallStackClassLoader, since the call-stack search stops
2091       at the ProxyInputStream subclass. However, it is convenient
2092       for two reasons. One is that it means that the
2093       ProxyInputStream subclass can be accessed directly, without
2094       using reflection. The other is that it avoids build problems,
2095       since usually stubs are created after other classes are
2096       compiled, so we can't access them from this class without,
2097       again, using reflection.
2098
2099       The strings below encode the following two Java classes,
2100       compiled using J2SE 1.4.2 with javac -g:none.
2101
2102    package com.sun.jmx.remote.internal;
2103
2104    import org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub;
2105
2106    import org.omg.CORBA.portable.ApplicationException;
2107    import org.omg.CORBA.portable.InputStream;
2108    import org.omg.CORBA.portable.OutputStream;
2109    import org.omg.CORBA.portable.RemarshalException;
2110
2111    public class ProxyStub extends _RMIConnection_Stub {
2112        public InputStream _invoke(OutputStream out)
2113            throws ApplicationException, RemarshalException {
2114                try {
2115            return new PInputStream(super._invoke(out));
2116                } catch (ApplicationException e) {
2117                    InputStream pis = new PInputStream(e.getInputStream());
2118                    throw new ApplicationException(e.getId(), pis);
2119                }
2120        }
2121
2122        public void _releaseReply(InputStream in) {
2123        PInputStream pis = (PInputStream) in;
2124        super._releaseReply(pis.getProxiedInputStream());
2125        }
2126    }
2127
2128    package com.sun.jmx.remote.internal;
2129
2130    public class PInputStream extends ProxyInputStream {
2131        public PInputStream(org.omg.CORBA.portable.InputStream in) {
2132        super(in);
2133        }
2134
2135        public org.omg.CORBA.Any read_any() {
2136        return in.read_any();
2137        }
2138
2139        public java.io.Serializable read_value(Class clz) {
2140        return narrow().read_value(clz);
2141        }
2142    }
2143
2144
2145     */

2146    private static final String JavaDoc iiopConnectionStubClassName =
2147    "org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub";
2148    private static final String JavaDoc proxyStubClassName =
2149    "com.sun.jmx.remote.internal.ProxyStub";
2150    private static final String JavaDoc pInputStreamClassName =
2151    "com.sun.jmx.remote.internal.PInputStream";
2152    private static final Class JavaDoc proxyStubClass;
2153    static {
2154    final String JavaDoc proxyStubByteCodeString =
2155        "\312\376\272\276\0\0\0.\0)\12\0\14\0\26\7\0\27\12\0\14\0\30\12"+
2156        "\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"+
2157        "\36\12\0\14\0\37\7\0\40\7\0!\1\0\6<init>\1\0\3()V\1\0\4Code\1"+
2158        "\0\7_invoke\1\0K(Lorg/omg/CORBA/portable/OutputStream;)Lorg/o"+
2159        "mg/CORBA/portable/InputStream;\1\0\12Exceptions\7\0\"\1\0\15_"+
2160        "releaseReply\1\0'(Lorg/omg/CORBA/portable/InputStream;)V\14\0"+
2161        "\15\0\16\1\0(com/sun/jmx/remote/internal/PInputStream\14\0\20"+
2162        "\0\21\14\0\15\0\25\1\0+org/omg/CORBA/portable/ApplicationExce"+
2163        "ption\14\0#\0$\14\0%\0&\14\0\15\0'\14\0(\0$\14\0\24\0\25\1\0%"+
2164        "com/sun/jmx/remote/internal/ProxyStub\1\0<org/omg/stub/javax/"+
2165        "management/remote/rmi/_RMIConnection_Stub\1\0)org/omg/CORBA/p"+
2166        "ortable/RemarshalException\1\0\16getInputStream\1\0&()Lorg/om"+
2167        "g/CORBA/portable/InputStream;\1\0\5getId\1\0\24()Ljava/lang/S"+
2168        "tring;\1\09(Ljava/lang/String;Lorg/omg/CORBA/portable/InputSt"+
2169        "ream;)V\1\0\25getProxiedInputStream\0!\0\13\0\14\0\0\0\0\0\3\0"+
2170        "\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"+
2171        "\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*"+
2172        "+\267\0\3\267\0\4\260M\273\0\2Y,\266\0\6\267\0\4N\273\0\5Y,\266"+
2173        "\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"+
2174        "\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"+
2175        "\0\13+\300\0\2\266\0\11L*+\267\0\12\261\0\0\0\0\0\0";
2176    final String JavaDoc pInputStreamByteCodeString =
2177        "\312\376\272\276\0\0\0.\0\36\12\0\7\0\17\11\0\6\0\20\12\0\21\0"+
2178        "\22\12\0\6\0\23\12\0\24\0\25\7\0\26\7\0\27\1\0\6<init>\1\0'(L"+
2179        "org/omg/CORBA/portable/InputStream;)V\1\0\4Code\1\0\10read_an"+
2180        "y\1\0\25()Lorg/omg/CORBA/Any;\1\0\12read_value\1\0)(Ljava/lan"+
2181        "g/Class;)Ljava/io/Serializable;\14\0\10\0\11\14\0\30\0\31\7\0"+
2182        "\32\14\0\13\0\14\14\0\33\0\34\7\0\35\14\0\15\0\16\1\0(com/sun"+
2183        "/jmx/remote/internal/PInputStream\1\0,com/sun/jmx/remote/inte"+
2184        "rnal/ProxyInputStream\1\0\2in\1\0$Lorg/omg/CORBA/portable/Inp"+
2185        "utStream;\1\0\"org/omg/CORBA/portable/InputStream\1\0\6narrow"+
2186        "\1\0*()Lorg/omg/CORBA_2_3/portable/InputStream;\1\0&org/omg/C"+
2187        "ORBA_2_3/portable/InputStream\0!\0\6\0\7\0\0\0\0\0\3\0\1\0\10"+
2188        "\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"+
2189        "\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"+
2190        "\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"+
2191        "\11*\266\0\4+\266\0\5\260\0\0\0\0\0\0";
2192    final byte[] proxyStubByteCode =
2193        NoCallStackClassLoader.stringToBytes(proxyStubByteCodeString);
2194    final byte[] pInputStreamByteCode =
2195        NoCallStackClassLoader.stringToBytes(pInputStreamByteCodeString);
2196    final String JavaDoc[] classNames={proxyStubClassName, pInputStreamClassName};
2197    final byte[][] byteCodes = {proxyStubByteCode, pInputStreamByteCode};
2198    final String JavaDoc[] otherClassNames = {
2199        iiopConnectionStubClassName,
2200        ProxyInputStream.class.getName(),
2201    };
2202    PrivilegedExceptionAction JavaDoc action = new PrivilegedExceptionAction JavaDoc() {
2203        public Object JavaDoc run() throws Exception JavaDoc {
2204        Class JavaDoc thisClass = RMIConnector JavaDoc.class;
2205        ClassLoader JavaDoc thisLoader = thisClass.getClassLoader();
2206        ProtectionDomain JavaDoc thisProtectionDomain =
2207            thisClass.getProtectionDomain();
2208        ClassLoader JavaDoc cl =
2209            new NoCallStackClassLoader JavaDoc(classNames,
2210                           byteCodes,
2211                           otherClassNames,
2212                           thisLoader,
2213                           thisProtectionDomain);
2214        return cl.loadClass(proxyStubClassName);
2215        }
2216    };
2217    Class JavaDoc stubClass;
2218    try {
2219        stubClass = (Class JavaDoc) AccessController.doPrivileged(action);
2220    } catch (Exception JavaDoc e) {
2221        logger.error("<clinit>",
2222           "Unexpected exception making shadow IIOP stub class: "+e);
2223        logger.debug("<clinit>",e);
2224        stubClass = null;
2225    }
2226    proxyStubClass = stubClass;
2227    }
2228
2229    private static RMIConnection JavaDoc shadowIiopStub(Stub JavaDoc stub)
2230        throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
2231    Stub JavaDoc proxyStub = (Stub JavaDoc) proxyStubClass.newInstance();
2232    proxyStub._set_delegate(stub._get_delegate());
2233    return (RMIConnection JavaDoc) proxyStub;
2234    }
2235
2236    private static RMIConnection JavaDoc getConnection(RMIServer JavaDoc server,
2237                           Object JavaDoc credentials)
2238        throws IOException JavaDoc {
2239    RMIConnection JavaDoc c = server.newClient(credentials);
2240    try {
2241        if (c.getClass() == rmiConnectionImplStubClass)
2242        return shadowJrmpStub((RemoteObject JavaDoc) c);
2243        if (c.getClass().getName().equals(iiopConnectionStubClassName))
2244        return shadowIiopStub((Stub JavaDoc) c);
2245        logger.trace("getConnection",
2246             "Did not wrap " + c.getClass() + " to foil " +
2247             "stack search for classes: class loading semantics " +
2248             "may be incorrect");
2249    } catch (Exception JavaDoc e) {
2250        logger.error("getConnection",
2251             "Could not wrap " + c.getClass() + " to foil " +
2252             "stack search for classes: class loading semantics " +
2253             "may be incorrect: " + e);
2254        logger.debug("getConnection",e);
2255        // so just return the original stub, which will work for all
2256
// but the most exotic class loading situations
2257
}
2258    return c;
2259    }
2260
2261    private static byte[] base64ToByteArray(String JavaDoc s) {
2262        int sLen = s.length();
2263        int numGroups = sLen/4;
2264        if (4*numGroups != sLen)
2265            throw new IllegalArgumentException JavaDoc(
2266                "String length must be a multiple of four.");
2267        int missingBytesInLastGroup = 0;
2268        int numFullGroups = numGroups;
2269        if (sLen != 0) {
2270            if (s.charAt(sLen-1) == '=') {
2271                missingBytesInLastGroup++;
2272                numFullGroups--;
2273            }
2274            if (s.charAt(sLen-2) == '=')
2275                missingBytesInLastGroup++;
2276        }
2277        byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
2278
2279        // Translate all full groups from base64 to byte array elements
2280
int inCursor = 0, outCursor = 0;
2281        for (int i=0; i<numFullGroups; i++) {
2282            int ch0 = base64toInt(s.charAt(inCursor++));
2283            int ch1 = base64toInt(s.charAt(inCursor++));
2284            int ch2 = base64toInt(s.charAt(inCursor++));
2285            int ch3 = base64toInt(s.charAt(inCursor++));
2286            result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
2287            result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
2288            result[outCursor++] = (byte) ((ch2 << 6) | ch3);
2289        }
2290
2291        // Translate partial group, if present
2292
if (missingBytesInLastGroup != 0) {
2293            int ch0 = base64toInt(s.charAt(inCursor++));
2294            int ch1 = base64toInt(s.charAt(inCursor++));
2295            result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
2296
2297            if (missingBytesInLastGroup == 1) {
2298                int ch2 = base64toInt(s.charAt(inCursor++));
2299                result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
2300            }
2301        }
2302        // assert inCursor == s.length()-missingBytesInLastGroup;
2303
// assert outCursor == result.length;
2304
return result;
2305    }
2306
2307    /**
2308     * Translates the specified character, which is assumed to be in the
2309     * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
2310     *
2311     * @throw IllegalArgumentException if
2312     * c is not in the Base64 Alphabet.
2313     */

2314    private static int base64toInt(char c) {
2315    int result;
2316
2317    if (c >= base64ToInt.length)
2318        result = -1;
2319        else
2320        result = base64ToInt[c];
2321
2322        if (result < 0)
2323            throw new IllegalArgumentException JavaDoc("Illegal character " + c);
2324        return result;
2325    }
2326
2327    /**
2328     * This array is a lookup table that translates unicode characters
2329     * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
2330     * into their 6-bit positive integer equivalents. Characters that
2331     * are not in the Base64 alphabet but fall within the bounds of the
2332     * array are translated to -1.
2333     */

2334    private static final byte base64ToInt[] = {
2335        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2336        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2337        -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
2338        55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
2339        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2340        24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
2341        35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
2342    };
2343
2344    //--------------------------------------------------------------------
2345
// Private stuff - Find / Set default class loader
2346
//--------------------------------------------------------------------
2347
private ClassLoader JavaDoc pushDefaultClassLoader() {
2348    final Thread JavaDoc t = Thread.currentThread();
2349        final ClassLoader JavaDoc old = t.getContextClassLoader();
2350        if (defaultClassLoader != null)
2351        AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
2352            public Object JavaDoc run() {
2353            t.setContextClassLoader(defaultClassLoader);
2354            return null;
2355            }
2356        });
2357        return old;
2358    }
2359
2360    private void popDefaultClassLoader(final ClassLoader JavaDoc old) {
2361    AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
2362        public Object JavaDoc run() {
2363            Thread.currentThread().setContextClassLoader(old);
2364            return null;
2365        }
2366        });
2367    }
2368
2369    //--------------------------------------------------------------------
2370
// Private variables
2371
//--------------------------------------------------------------------
2372
/**
2373     * @serial The RMIServer stub of the RMI JMX Connector server to
2374     * which this client connector is (or will be) connected. This
2375     * field can be null when <var>jmxServiceURL</var> is not
2376     * null. This includes the case where <var>jmxServiceURL</var>
2377     * contains a serialized RMIServer stub. If both
2378     * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
2379     * serialization will fail.
2380     *
2381     * @see #RMIConnector(RMIServer,Map)
2382     **/

2383    private final RMIServer JavaDoc rmiServer;
2384
2385    /**
2386     * @serial The JMXServiceURL of the RMI JMX Connector server to
2387     * which this client connector will be connected. This field can
2388     * be null when <var>rmiServer</var> is not null. If both
2389     * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
2390     * serialization will fail.
2391     *
2392     * @see #RMIConnector(JMXServiceURL,Map)
2393     **/

2394    private final JMXServiceURL JavaDoc jmxServiceURL;
2395
2396    // ---------------------------------------------------------
2397
// WARNING - WARNING - WARNING - WARNING - WARNING - WARNING
2398
// ---------------------------------------------------------
2399
// Any transient variable which needs to be initialized should
2400
// be initialized in the method initTransient()
2401
private transient Map JavaDoc env;
2402    private transient ClassLoader JavaDoc defaultClassLoader;
2403    private transient RMIConnection JavaDoc connection;
2404    private transient String JavaDoc connectionId;
2405
2406    private long clientNotifID = 0;
2407
2408    private transient WeakHashMap JavaDoc rmbscMap;
2409
2410    private transient RMINotifClient rmiNotifClient;
2411    // = new RMINotifClient(new Integer(0));
2412

2413    private transient long clientNotifCounter = 0;
2414
2415    private transient boolean connected;
2416    // = false;
2417
private transient boolean terminated;
2418    // = false;
2419

2420    private transient Exception JavaDoc closeException;
2421
2422    private transient NotificationBroadcasterSupport JavaDoc connectionBroadcaster;
2423
2424    private transient ClientCommunicatorAdmin communicatorAdmin;
2425
2426    /**
2427     * A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to
2428     * connect unconnected stubs.
2429     **/

2430    private static WeakReference JavaDoc orb = null;
2431
2432    private static final ObjectName JavaDoc delegateName;
2433    static {
2434    try {
2435        delegateName =
2436        new ObjectName JavaDoc("JMImplementation:type=MBeanServerDelegate");
2437    } catch (MalformedObjectNameException JavaDoc e) {
2438        Error JavaDoc error = new Error JavaDoc("Can't initialize delegateName");
2439        EnvHelp.initCause(error, e);
2440        throw error;
2441    }
2442    }
2443
2444    // TRACES & DEBUG
2445
//---------------
2446
private static String JavaDoc objects(final Object JavaDoc[] objs) {
2447    if (objs == null)
2448        return "null";
2449    else
2450        return Arrays.asList(objs).toString();
2451    }
2452
2453    private static String JavaDoc strings(final String JavaDoc[] strs) {
2454    return objects(strs);
2455    }
2456}
2457
Popular Tags