Save This Page
Home » openjdk-7 » javax » management » remote » rmi » [javadoc | source]
    1   /*
    2    * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.management.remote.rmi;
   27   
   28   import static com.sun.jmx.mbeanserver.Util.cast;
   29   import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
   30   import com.sun.jmx.remote.internal.ServerNotifForwarder;
   31   import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
   32   import com.sun.jmx.remote.security.SubjectDelegator;
   33   import com.sun.jmx.remote.util.ClassLoaderWithRepository;
   34   import com.sun.jmx.remote.util.ClassLogger;
   35   import com.sun.jmx.remote.util.EnvHelp;
   36   import com.sun.jmx.remote.util.OrderClassLoaders;
   37   
   38   import java.io.IOException;
   39   import java.rmi.MarshalledObject;
   40   import java.rmi.UnmarshalException;
   41   import java.rmi.server.Unreferenced;
   42   import java.security.AccessControlContext;
   43   import java.security.AccessController;
   44   import java.security.PrivilegedAction;
   45   import java.security.PrivilegedActionException;
   46   import java.security.PrivilegedExceptionAction;
   47   import java.util.Arrays;
   48   import java.util.Collections;
   49   import java.util.Map;
   50   import java.util.Set;
   51   
   52   import javax.management.Attribute;
   53   import javax.management.AttributeList;
   54   import javax.management.AttributeNotFoundException;
   55   import javax.management.InstanceAlreadyExistsException;
   56   import javax.management.InstanceNotFoundException;
   57   import javax.management.IntrospectionException;
   58   import javax.management.InvalidAttributeValueException;
   59   import javax.management.ListenerNotFoundException;
   60   import javax.management.MBeanException;
   61   import javax.management.MBeanInfo;
   62   import javax.management.MBeanRegistrationException;
   63   import javax.management.MBeanServer;
   64   import javax.management.NotCompliantMBeanException;
   65   import javax.management.NotificationFilter;
   66   import javax.management.ObjectInstance;
   67   import javax.management.ObjectName;
   68   import javax.management.QueryExp;
   69   import javax.management.ReflectionException;
   70   import javax.management.RuntimeOperationsException;
   71   import javax.management.loading.ClassLoaderRepository;
   72   import javax.management.remote.JMXServerErrorException;
   73   import javax.management.remote.NotificationResult;
   74   import javax.management.remote.TargetedNotification;
   75   import javax.security.auth.Subject;
   76   
   77   /**
   78    * <p>Implementation of the {@link RMIConnection} interface.  User
   79    * code will not usually reference this class.</p>
   80    *
   81    * @since 1.5
   82    */
   83   /*
   84    * Notice that we omit the type parameter from MarshalledObject everywhere,
   85    * even though it would add useful information to the documentation.  The
   86    * reason is that it was only added in Mustang (Java SE 6), whereas versions
   87    * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
   88    * commitments for JSR 255.
   89    */
   90   public class RMIConnectionImpl implements RMIConnection, Unreferenced {
   91   
   92       /**
   93        * Constructs a new {@link RMIConnection}. This connection can be
   94        * used with either the JRMP or IIOP transport. This object does
   95        * not export itself: it is the responsibility of the caller to
   96        * export it appropriately (see {@link
   97        * RMIJRMPServerImpl#makeClient(String,Subject)} and {@link
   98        * RMIIIOPServerImpl#makeClient(String,Subject)}.
   99        *
  100        * @param rmiServer The RMIServerImpl object for which this
  101        * connection is created.  The behavior is unspecified if this
  102        * parameter is null.
  103        * @param connectionId The ID for this connection.  The behavior
  104        * is unspecified if this parameter is null.
  105        * @param defaultClassLoader The default ClassLoader to be used
  106        * when deserializing marshalled objects.  Can be null, to signify
  107        * the bootstrap class loader.
  108        * @param subject the authenticated subject to be used for
  109        * authorization.  Can be null, to signify that no subject has
  110        * been authenticated.
  111        * @param env the environment containing attributes for the new
  112        * <code>RMIServerImpl</code>.  Can be null, equivalent to an
  113        * empty map.
  114        */
  115       public RMIConnectionImpl(RMIServerImpl rmiServer,
  116                                String connectionId,
  117                                ClassLoader defaultClassLoader,
  118                                Subject subject,
  119                                Map<String,?> env) {
  120           if (rmiServer == null || connectionId == null)
  121               throw new NullPointerException("Illegal null argument");
  122           if (env == null)
  123               env = Collections.emptyMap();
  124           this.rmiServer = rmiServer;
  125           this.connectionId = connectionId;
  126           this.defaultClassLoader = defaultClassLoader;
  127   
  128           this.subjectDelegator = new SubjectDelegator();
  129           this.subject = subject;
  130           if (subject == null) {
  131               this.acc = null;
  132               this.removeCallerContext = false;
  133           } else {
  134               this.removeCallerContext =
  135                   SubjectDelegator.checkRemoveCallerContext(subject);
  136               if (this.removeCallerContext) {
  137                   this.acc =
  138                       JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
  139               } else {
  140                   this.acc =
  141                       JMXSubjectDomainCombiner.getContext(subject);
  142               }
  143           }
  144           this.mbeanServer = rmiServer.getMBeanServer();
  145   
  146           final ClassLoader dcl = defaultClassLoader;
  147           this.classLoaderWithRepository =
  148               AccessController.doPrivileged(
  149                   new PrivilegedAction<ClassLoaderWithRepository>() {
  150                       public ClassLoaderWithRepository run() {
  151                           return new ClassLoaderWithRepository(
  152                                                 getClassLoaderRepository(),
  153                                                 dcl);
  154                       }
  155                   });
  156   
  157           serverCommunicatorAdmin = new
  158             RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
  159   
  160           this.env = env;
  161       }
  162   
  163       private synchronized ServerNotifForwarder getServerNotifFwd() {
  164           // Lazily created when first use. Mainly when
  165           // addNotificationListener is first called.
  166           if (serverNotifForwarder == null)
  167               serverNotifForwarder =
  168                   new ServerNotifForwarder(mbeanServer,
  169                                            env,
  170                                            rmiServer.getNotifBuffer(),
  171                                            connectionId);
  172           return serverNotifForwarder;
  173       }
  174   
  175       public String getConnectionId() throws IOException {
  176           // We should call reqIncomming() here... shouldn't we?
  177           return connectionId;
  178       }
  179   
  180       public void close() throws IOException {
  181           final boolean debug = logger.debugOn();
  182           final String  idstr = (debug?"["+this.toString()+"]":null);
  183   
  184           synchronized (this) {
  185               if (terminated) {
  186                   if (debug) logger.debug("close",idstr + " already terminated.");
  187                   return;
  188               }
  189   
  190               if (debug) logger.debug("close",idstr + " closing.");
  191   
  192               terminated = true;
  193   
  194               if (serverCommunicatorAdmin != null) {
  195                   serverCommunicatorAdmin.terminate();
  196               }
  197   
  198               if (serverNotifForwarder != null) {
  199                   serverNotifForwarder.terminate();
  200               }
  201           }
  202   
  203           rmiServer.clientClosed(this);
  204   
  205           if (debug) logger.debug("close",idstr + " closed.");
  206       }
  207   
  208       public void unreferenced() {
  209           logger.debug("unreferenced", "called");
  210           try {
  211               close();
  212               logger.debug("unreferenced", "done");
  213           } catch (IOException e) {
  214               logger.fine("unreferenced", e);
  215           }
  216       }
  217   
  218       //-------------------------------------------------------------------------
  219       // MBeanServerConnection Wrapper
  220       //-------------------------------------------------------------------------
  221   
  222       public ObjectInstance createMBean(String className,
  223                                         ObjectName name,
  224                                         Subject delegationSubject)
  225           throws
  226           ReflectionException,
  227           InstanceAlreadyExistsException,
  228           MBeanRegistrationException,
  229           MBeanException,
  230           NotCompliantMBeanException,
  231           IOException {
  232           try {
  233               final Object params[] =
  234                   new Object[] { className, name };
  235   
  236               if (logger.debugOn())
  237                   logger.debug("createMBean(String,ObjectName)",
  238                                "connectionId=" + connectionId +", className=" +
  239                                className+", name=" + name);
  240   
  241               return (ObjectInstance)
  242                   doPrivilegedOperation(
  243                     CREATE_MBEAN,
  244                     params,
  245                     delegationSubject);
  246           } catch (PrivilegedActionException pe) {
  247               Exception e = extractException(pe);
  248               if (e instanceof ReflectionException)
  249                   throw (ReflectionException) e;
  250               if (e instanceof InstanceAlreadyExistsException)
  251                   throw (InstanceAlreadyExistsException) e;
  252               if (e instanceof MBeanRegistrationException)
  253                   throw (MBeanRegistrationException) e;
  254               if (e instanceof MBeanException)
  255                   throw (MBeanException) e;
  256               if (e instanceof NotCompliantMBeanException)
  257                   throw (NotCompliantMBeanException) e;
  258               if (e instanceof IOException)
  259                   throw (IOException) e;
  260               throw newIOException("Got unexpected server exception: " + e, e);
  261           }
  262       }
  263   
  264       public ObjectInstance createMBean(String className,
  265                                         ObjectName name,
  266                                         ObjectName loaderName,
  267                                         Subject delegationSubject)
  268           throws
  269           ReflectionException,
  270           InstanceAlreadyExistsException,
  271           MBeanRegistrationException,
  272           MBeanException,
  273           NotCompliantMBeanException,
  274           InstanceNotFoundException,
  275           IOException {
  276           try {
  277               final Object params[] =
  278                   new Object[] { className, name, loaderName };
  279   
  280               if (logger.debugOn())
  281                   logger.debug("createMBean(String,ObjectName,ObjectName)",
  282                         "connectionId=" + connectionId
  283                         +", className=" + className
  284                         +", name=" + name
  285                         +", loaderName=" + loaderName);
  286   
  287               return (ObjectInstance)
  288                   doPrivilegedOperation(
  289                     CREATE_MBEAN_LOADER,
  290                     params,
  291                     delegationSubject);
  292           } catch (PrivilegedActionException pe) {
  293               Exception e = extractException(pe);
  294               if (e instanceof ReflectionException)
  295                   throw (ReflectionException) e;
  296               if (e instanceof InstanceAlreadyExistsException)
  297                   throw (InstanceAlreadyExistsException) e;
  298               if (e instanceof MBeanRegistrationException)
  299                   throw (MBeanRegistrationException) e;
  300               if (e instanceof MBeanException)
  301                   throw (MBeanException) e;
  302               if (e instanceof NotCompliantMBeanException)
  303                   throw (NotCompliantMBeanException) e;
  304               if (e instanceof InstanceNotFoundException)
  305                   throw (InstanceNotFoundException) e;
  306               if (e instanceof IOException)
  307                   throw (IOException) e;
  308               throw newIOException("Got unexpected server exception: " + e, e);
  309           }
  310       }
  311   
  312       public ObjectInstance createMBean(String className,
  313                                         ObjectName name,
  314                                         MarshalledObject params,
  315                                         String signature[],
  316                                         Subject delegationSubject)
  317           throws
  318           ReflectionException,
  319           InstanceAlreadyExistsException,
  320           MBeanRegistrationException,
  321           MBeanException,
  322           NotCompliantMBeanException,
  323           IOException {
  324   
  325           final Object[] values;
  326           final boolean debug = logger.debugOn();
  327   
  328           if (debug) logger.debug(
  329                     "createMBean(String,ObjectName,Object[],String[])",
  330                     "connectionId=" + connectionId
  331                     +", unwrapping parameters using classLoaderWithRepository.");
  332   
  333           values =
  334               nullIsEmpty(unwrap(params, classLoaderWithRepository, Object[].class));
  335   
  336           try {
  337               final Object params2[] =
  338                   new Object[] { className, name, values,
  339                                  nullIsEmpty(signature) };
  340   
  341               if (debug)
  342                  logger.debug("createMBean(String,ObjectName,Object[],String[])",
  343                                "connectionId=" + connectionId
  344                                +", className=" + className
  345                                +", name=" + name
  346                                +", params=" + objects(values)
  347                                +", signature=" + strings(signature));
  348   
  349               return (ObjectInstance)
  350                   doPrivilegedOperation(
  351                     CREATE_MBEAN_PARAMS,
  352                     params2,
  353                     delegationSubject);
  354           } catch (PrivilegedActionException pe) {
  355               Exception e = extractException(pe);
  356               if (e instanceof ReflectionException)
  357                   throw (ReflectionException) e;
  358               if (e instanceof InstanceAlreadyExistsException)
  359                   throw (InstanceAlreadyExistsException) e;
  360               if (e instanceof MBeanRegistrationException)
  361                   throw (MBeanRegistrationException) e;
  362               if (e instanceof MBeanException)
  363                   throw (MBeanException) e;
  364               if (e instanceof NotCompliantMBeanException)
  365                   throw (NotCompliantMBeanException) e;
  366               if (e instanceof IOException)
  367                   throw (IOException) e;
  368               throw newIOException("Got unexpected server exception: " + e, e);
  369           }
  370       }
  371   
  372       public ObjectInstance createMBean(String className,
  373                                    ObjectName name,
  374                                    ObjectName loaderName,
  375                                    MarshalledObject params,
  376                                    String signature[],
  377                                    Subject delegationSubject)
  378           throws
  379           ReflectionException,
  380           InstanceAlreadyExistsException,
  381           MBeanRegistrationException,
  382           MBeanException,
  383           NotCompliantMBeanException,
  384           InstanceNotFoundException,
  385           IOException {
  386   
  387           final Object[] values;
  388           final boolean debug = logger.debugOn();
  389   
  390           if (debug) logger.debug(
  391                    "createMBean(String,ObjectName,ObjectName,Object[],String[])",
  392                    "connectionId=" + connectionId
  393                    +", unwrapping params with MBean extended ClassLoader.");
  394   
  395           values = nullIsEmpty(unwrap(params,
  396                                       getClassLoader(loaderName),
  397                                       defaultClassLoader,
  398                                       Object[].class));
  399   
  400           try {
  401               final Object params2[] =
  402                  new Object[] { className, name, loaderName, values,
  403                                 nullIsEmpty(signature) };
  404   
  405              if (debug) logger.debug(
  406                    "createMBean(String,ObjectName,ObjectName,Object[],String[])",
  407                    "connectionId=" + connectionId
  408                    +", className=" + className
  409                    +", name=" + name
  410                    +", loaderName=" + loaderName
  411                    +", params=" + objects(values)
  412                    +", signature=" + strings(signature));
  413   
  414               return (ObjectInstance)
  415                   doPrivilegedOperation(
  416                     CREATE_MBEAN_LOADER_PARAMS,
  417                     params2,
  418                     delegationSubject);
  419           } catch (PrivilegedActionException pe) {
  420               Exception e = extractException(pe);
  421               if (e instanceof ReflectionException)
  422                   throw (ReflectionException) e;
  423               if (e instanceof InstanceAlreadyExistsException)
  424                   throw (InstanceAlreadyExistsException) e;
  425               if (e instanceof MBeanRegistrationException)
  426                   throw (MBeanRegistrationException) e;
  427               if (e instanceof MBeanException)
  428                   throw (MBeanException) e;
  429               if (e instanceof NotCompliantMBeanException)
  430                   throw (NotCompliantMBeanException) e;
  431               if (e instanceof InstanceNotFoundException)
  432                   throw (InstanceNotFoundException) e;
  433               if (e instanceof IOException)
  434                   throw (IOException) e;
  435               throw newIOException("Got unexpected server exception: " + e, e);
  436           }
  437       }
  438   
  439       public void unregisterMBean(ObjectName name, Subject delegationSubject)
  440           throws
  441           InstanceNotFoundException,
  442           MBeanRegistrationException,
  443           IOException {
  444           try {
  445               final Object params[] = new Object[] { name };
  446   
  447               if (logger.debugOn()) logger.debug("unregisterMBean",
  448                    "connectionId=" + connectionId
  449                    +", name="+name);
  450   
  451               doPrivilegedOperation(
  452                 UNREGISTER_MBEAN,
  453                 params,
  454                 delegationSubject);
  455           } catch (PrivilegedActionException pe) {
  456               Exception e = extractException(pe);
  457               if (e instanceof InstanceNotFoundException)
  458                   throw (InstanceNotFoundException) e;
  459               if (e instanceof MBeanRegistrationException)
  460                   throw (MBeanRegistrationException) e;
  461               if (e instanceof IOException)
  462                   throw (IOException) e;
  463               throw newIOException("Got unexpected server exception: " + e, e);
  464           }
  465       }
  466   
  467       public ObjectInstance getObjectInstance(ObjectName name,
  468                                               Subject delegationSubject)
  469           throws
  470           InstanceNotFoundException,
  471           IOException {
  472   
  473           checkNonNull("ObjectName", name);
  474   
  475           try {
  476               final Object params[] = new Object[] { name };
  477   
  478               if (logger.debugOn()) logger.debug("getObjectInstance",
  479                    "connectionId=" + connectionId
  480                    +", name="+name);
  481   
  482               return (ObjectInstance)
  483                   doPrivilegedOperation(
  484                     GET_OBJECT_INSTANCE,
  485                     params,
  486                     delegationSubject);
  487           } catch (PrivilegedActionException pe) {
  488               Exception e = extractException(pe);
  489               if (e instanceof InstanceNotFoundException)
  490                   throw (InstanceNotFoundException) e;
  491               if (e instanceof IOException)
  492                   throw (IOException) e;
  493               throw newIOException("Got unexpected server exception: " + e, e);
  494           }
  495       }
  496   
  497       public Set<ObjectInstance>
  498           queryMBeans(ObjectName name,
  499                       MarshalledObject query,
  500                       Subject delegationSubject)
  501           throws IOException {
  502           final QueryExp queryValue;
  503           final boolean debug=logger.debugOn();
  504   
  505           if (debug) logger.debug("queryMBeans",
  506                    "connectionId=" + connectionId
  507                    +" unwrapping query with defaultClassLoader.");
  508   
  509           queryValue = unwrap(query, defaultClassLoader, QueryExp.class);
  510   
  511           try {
  512               final Object params[] = new Object[] { name, queryValue };
  513   
  514               if (debug) logger.debug("queryMBeans",
  515                    "connectionId=" + connectionId
  516                    +", name="+name +", query="+query);
  517   
  518               return cast(
  519                   doPrivilegedOperation(
  520                     QUERY_MBEANS,
  521                     params,
  522                     delegationSubject));
  523           } catch (PrivilegedActionException pe) {
  524               Exception e = extractException(pe);
  525               if (e instanceof IOException)
  526                   throw (IOException) e;
  527               throw newIOException("Got unexpected server exception: " + e, e);
  528           }
  529       }
  530   
  531       public Set<ObjectName>
  532           queryNames(ObjectName name,
  533                      MarshalledObject query,
  534                      Subject delegationSubject)
  535           throws IOException {
  536           final QueryExp queryValue;
  537           final boolean debug=logger.debugOn();
  538   
  539           if (debug) logger.debug("queryNames",
  540                    "connectionId=" + connectionId
  541                    +" unwrapping query with defaultClassLoader.");
  542   
  543           queryValue = unwrap(query, defaultClassLoader, QueryExp.class);
  544   
  545           try {
  546               final Object params[] = new Object[] { name, queryValue };
  547   
  548               if (debug) logger.debug("queryNames",
  549                    "connectionId=" + connectionId
  550                    +", name="+name +", query="+query);
  551   
  552               return cast(
  553                   doPrivilegedOperation(
  554                     QUERY_NAMES,
  555                     params,
  556                     delegationSubject));
  557           } catch (PrivilegedActionException pe) {
  558               Exception e = extractException(pe);
  559               if (e instanceof IOException)
  560                   throw (IOException) e;
  561               throw newIOException("Got unexpected server exception: " + e, e);
  562           }
  563       }
  564   
  565       public boolean isRegistered(ObjectName name,
  566                                   Subject delegationSubject) throws IOException {
  567           try {
  568               final Object params[] = new Object[] { name };
  569               return ((Boolean)
  570                   doPrivilegedOperation(
  571                     IS_REGISTERED,
  572                     params,
  573                     delegationSubject)).booleanValue();
  574           } catch (PrivilegedActionException pe) {
  575               Exception e = extractException(pe);
  576               if (e instanceof IOException)
  577                   throw (IOException) e;
  578               throw newIOException("Got unexpected server exception: " + e, e);
  579           }
  580       }
  581   
  582       public Integer getMBeanCount(Subject delegationSubject)
  583           throws IOException {
  584           try {
  585               final Object params[] = new Object[] { };
  586   
  587               if (logger.debugOn()) logger.debug("getMBeanCount",
  588                    "connectionId=" + connectionId);
  589   
  590               return (Integer)
  591                   doPrivilegedOperation(
  592                     GET_MBEAN_COUNT,
  593                     params,
  594                     delegationSubject);
  595           } catch (PrivilegedActionException pe) {
  596               Exception e = extractException(pe);
  597               if (e instanceof IOException)
  598                   throw (IOException) e;
  599               throw newIOException("Got unexpected server exception: " + e, e);
  600           }
  601       }
  602   
  603       public Object getAttribute(ObjectName name,
  604                                  String attribute,
  605                                  Subject delegationSubject)
  606           throws
  607           MBeanException,
  608           AttributeNotFoundException,
  609           InstanceNotFoundException,
  610           ReflectionException,
  611           IOException {
  612           try {
  613               final Object params[] = new Object[] { name, attribute };
  614               if (logger.debugOn()) logger.debug("getAttribute",
  615                                      "connectionId=" + connectionId
  616                                      +", name=" + name
  617                                      +", attribute="+ attribute);
  618   
  619               return
  620                   doPrivilegedOperation(
  621                     GET_ATTRIBUTE,
  622                     params,
  623                     delegationSubject);
  624           } catch (PrivilegedActionException pe) {
  625               Exception e = extractException(pe);
  626               if (e instanceof MBeanException)
  627                   throw (MBeanException) e;
  628               if (e instanceof AttributeNotFoundException)
  629                   throw (AttributeNotFoundException) e;
  630               if (e instanceof InstanceNotFoundException)
  631                   throw (InstanceNotFoundException) e;
  632               if (e instanceof ReflectionException)
  633                   throw (ReflectionException) e;
  634               if (e instanceof IOException)
  635                   throw (IOException) e;
  636               throw newIOException("Got unexpected server exception: " + e, e);
  637           }
  638       }
  639   
  640       public AttributeList getAttributes(ObjectName name,
  641                                          String[] attributes,
  642                                          Subject delegationSubject)
  643           throws
  644           InstanceNotFoundException,
  645           ReflectionException,
  646           IOException {
  647           try {
  648               final Object params[] = new Object[] { name, attributes };
  649   
  650               if (logger.debugOn()) logger.debug("getAttributes",
  651                                      "connectionId=" + connectionId
  652                                      +", name=" + name
  653                                      +", attributes="+ strings(attributes));
  654   
  655               return (AttributeList)
  656                   doPrivilegedOperation(
  657                     GET_ATTRIBUTES,
  658                     params,
  659                     delegationSubject);
  660           } catch (PrivilegedActionException pe) {
  661               Exception e = extractException(pe);
  662               if (e instanceof InstanceNotFoundException)
  663                   throw (InstanceNotFoundException) e;
  664               if (e instanceof ReflectionException)
  665                   throw (ReflectionException) e;
  666               if (e instanceof IOException)
  667                   throw (IOException) e;
  668               throw newIOException("Got unexpected server exception: " + e, e);
  669           }
  670       }
  671   
  672       public void setAttribute(ObjectName name,
  673                                MarshalledObject attribute,
  674                                Subject delegationSubject)
  675           throws
  676           InstanceNotFoundException,
  677           AttributeNotFoundException,
  678           InvalidAttributeValueException,
  679           MBeanException,
  680           ReflectionException,
  681           IOException {
  682           final Attribute attr;
  683           final boolean debug=logger.debugOn();
  684   
  685           if (debug) logger.debug("setAttribute",
  686                    "connectionId=" + connectionId
  687                    +" unwrapping attribute with MBean extended ClassLoader.");
  688   
  689           attr = unwrap(attribute,
  690                         getClassLoaderFor(name),
  691                         defaultClassLoader,
  692                         Attribute.class);
  693   
  694           try {
  695               final Object params[] = new Object[] { name, attr };
  696   
  697               if (debug) logger.debug("setAttribute",
  698                                "connectionId=" + connectionId
  699                                +", name="+name
  700                                +", attribute="+attr);
  701   
  702               doPrivilegedOperation(
  703                 SET_ATTRIBUTE,
  704                 params,
  705                 delegationSubject);
  706           } catch (PrivilegedActionException pe) {
  707               Exception e = extractException(pe);
  708               if (e instanceof InstanceNotFoundException)
  709                   throw (InstanceNotFoundException) e;
  710               if (e instanceof AttributeNotFoundException)
  711                   throw (AttributeNotFoundException) e;
  712               if (e instanceof InvalidAttributeValueException)
  713                   throw (InvalidAttributeValueException) e;
  714               if (e instanceof MBeanException)
  715                   throw (MBeanException) e;
  716               if (e instanceof ReflectionException)
  717                   throw (ReflectionException) e;
  718               if (e instanceof IOException)
  719                   throw (IOException) e;
  720               throw newIOException("Got unexpected server exception: " + e, e);
  721           }
  722       }
  723   
  724       public AttributeList setAttributes(ObjectName name,
  725                            MarshalledObject attributes,
  726                            Subject delegationSubject)
  727           throws
  728           InstanceNotFoundException,
  729           ReflectionException,
  730           IOException {
  731           final AttributeList attrlist;
  732           final boolean debug=logger.debugOn();
  733   
  734           if (debug) logger.debug("setAttributes",
  735                    "connectionId=" + connectionId
  736                    +" unwrapping attributes with MBean extended ClassLoader.");
  737   
  738           attrlist =
  739               unwrap(attributes,
  740                      getClassLoaderFor(name),
  741                      defaultClassLoader,
  742                      AttributeList.class);
  743   
  744           try {
  745               final Object params[] = new Object[] { name, attrlist };
  746   
  747               if (debug) logger.debug("setAttributes",
  748                                "connectionId=" + connectionId
  749                                +", name="+name
  750                                +", attributes="+attrlist);
  751   
  752               return (AttributeList)
  753                   doPrivilegedOperation(
  754                     SET_ATTRIBUTES,
  755                     params,
  756                     delegationSubject);
  757           } catch (PrivilegedActionException pe) {
  758               Exception e = extractException(pe);
  759               if (e instanceof InstanceNotFoundException)
  760                   throw (InstanceNotFoundException) e;
  761               if (e instanceof ReflectionException)
  762                   throw (ReflectionException) e;
  763               if (e instanceof IOException)
  764                   throw (IOException) e;
  765               throw newIOException("Got unexpected server exception: " + e, e);
  766           }
  767       }
  768   
  769       public Object invoke(ObjectName name,
  770                            String operationName,
  771                            MarshalledObject params,
  772                            String signature[],
  773                            Subject delegationSubject)
  774           throws
  775           InstanceNotFoundException,
  776           MBeanException,
  777           ReflectionException,
  778           IOException {
  779   
  780           checkNonNull("ObjectName", name);
  781           checkNonNull("Operation name", operationName);
  782   
  783           final Object[] values;
  784           final boolean debug=logger.debugOn();
  785   
  786           if (debug) logger.debug("invoke",
  787                    "connectionId=" + connectionId
  788                    +" unwrapping params with MBean extended ClassLoader.");
  789   
  790           values = nullIsEmpty(unwrap(params,
  791                                       getClassLoaderFor(name),
  792                                       defaultClassLoader,
  793                                       Object[].class));
  794   
  795           try {
  796               final Object params2[] =
  797                   new Object[] { name, operationName, values,
  798                                  nullIsEmpty(signature) };
  799   
  800               if (debug) logger.debug("invoke",
  801                                "connectionId=" + connectionId
  802                                +", name="+name
  803                                +", operationName="+operationName
  804                                +", params="+objects(values)
  805                                +", signature="+strings(signature));
  806   
  807               return
  808                   doPrivilegedOperation(
  809                     INVOKE,
  810                     params2,
  811                     delegationSubject);
  812           } catch (PrivilegedActionException pe) {
  813               Exception e = extractException(pe);
  814               if (e instanceof InstanceNotFoundException)
  815                   throw (InstanceNotFoundException) e;
  816               if (e instanceof MBeanException)
  817                   throw (MBeanException) e;
  818               if (e instanceof ReflectionException)
  819                   throw (ReflectionException) e;
  820               if (e instanceof IOException)
  821                   throw (IOException) e;
  822               throw newIOException("Got unexpected server exception: " + e, e);
  823           }
  824       }
  825   
  826       public String getDefaultDomain(Subject delegationSubject)
  827           throws IOException {
  828           try {
  829               final Object params[] = new Object[] { };
  830   
  831               if (logger.debugOn())  logger.debug("getDefaultDomain",
  832                                       "connectionId=" + connectionId);
  833   
  834               return (String)
  835                   doPrivilegedOperation(
  836                     GET_DEFAULT_DOMAIN,
  837                     params,
  838                     delegationSubject);
  839           } catch (PrivilegedActionException pe) {
  840               Exception e = extractException(pe);
  841               if (e instanceof IOException)
  842                   throw (IOException) e;
  843               throw newIOException("Got unexpected server exception: " + e, e);
  844           }
  845       }
  846   
  847       public String[] getDomains(Subject delegationSubject) throws IOException {
  848           try {
  849               final Object params[] = new Object[] { };
  850   
  851               if (logger.debugOn())  logger.debug("getDomains",
  852                                       "connectionId=" + connectionId);
  853   
  854               return (String[])
  855                   doPrivilegedOperation(
  856                     GET_DOMAINS,
  857                     params,
  858                     delegationSubject);
  859           } catch (PrivilegedActionException pe) {
  860               Exception e = extractException(pe);
  861               if (e instanceof IOException)
  862                   throw (IOException) e;
  863               throw newIOException("Got unexpected server exception: " + e, e);
  864           }
  865       }
  866   
  867       public MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject)
  868           throws
  869           InstanceNotFoundException,
  870           IntrospectionException,
  871           ReflectionException,
  872           IOException {
  873   
  874           checkNonNull("ObjectName", name);
  875   
  876           try {
  877               final Object params[] = new Object[] { name };
  878   
  879               if (logger.debugOn())  logger.debug("getMBeanInfo",
  880                                       "connectionId=" + connectionId
  881                                       +", name="+name);
  882   
  883               return (MBeanInfo)
  884                   doPrivilegedOperation(
  885                     GET_MBEAN_INFO,
  886                     params,
  887                     delegationSubject);
  888           } catch (PrivilegedActionException pe) {
  889               Exception e = extractException(pe);
  890               if (e instanceof InstanceNotFoundException)
  891                   throw (InstanceNotFoundException) e;
  892               if (e instanceof IntrospectionException)
  893                   throw (IntrospectionException) e;
  894               if (e instanceof ReflectionException)
  895                   throw (ReflectionException) e;
  896               if (e instanceof IOException)
  897                   throw (IOException) e;
  898               throw newIOException("Got unexpected server exception: " + e, e);
  899           }
  900       }
  901   
  902       public boolean isInstanceOf(ObjectName name,
  903                                   String className,
  904                                   Subject delegationSubject)
  905           throws InstanceNotFoundException, IOException {
  906   
  907           checkNonNull("ObjectName", name);
  908   
  909           try {
  910               final Object params[] = new Object[] { name, className };
  911   
  912               if (logger.debugOn())  logger.debug("isInstanceOf",
  913                                       "connectionId=" + connectionId
  914                                       +", name="+name
  915                                       +", className="+className);
  916   
  917               return ((Boolean)
  918                   doPrivilegedOperation(
  919                     IS_INSTANCE_OF,
  920                     params,
  921                     delegationSubject)).booleanValue();
  922           } catch (PrivilegedActionException pe) {
  923               Exception e = extractException(pe);
  924               if (e instanceof InstanceNotFoundException)
  925                   throw (InstanceNotFoundException) e;
  926               if (e instanceof IOException)
  927                   throw (IOException) e;
  928               throw newIOException("Got unexpected server exception: " + e, e);
  929           }
  930       }
  931   
  932       public Integer[] addNotificationListeners(ObjectName[] names,
  933                         MarshalledObject[] filters,
  934                         Subject[] delegationSubjects)
  935               throws InstanceNotFoundException, IOException {
  936   
  937           if (names == null || filters == null) {
  938               throw new IllegalArgumentException("Got null arguments.");
  939           }
  940   
  941           Subject[] sbjs = (delegationSubjects != null) ? delegationSubjects :
  942           new Subject[names.length];
  943           if (names.length != filters.length || filters.length != sbjs.length) {
  944               final String msg =
  945                   "The value lengths of 3 parameters are not same.";
  946               throw new IllegalArgumentException(msg);
  947           }
  948   
  949           for (int i=0; i<names.length; i++) {
  950               if (names[i] == null) {
  951                   throw new IllegalArgumentException("Null Object name.");
  952               }
  953           }
  954   
  955           int i=0;
  956           ClassLoader targetCl;
  957           NotificationFilter[] filterValues =
  958           new NotificationFilter[names.length];
  959           Object params[];
  960           Integer[] ids = new Integer[names.length];
  961           final boolean debug=logger.debugOn();
  962   
  963           try {
  964               for (; i<names.length; i++) {
  965                   targetCl = getClassLoaderFor(names[i]);
  966   
  967                   if (debug) logger.debug("addNotificationListener"+
  968                                           "(ObjectName,NotificationFilter)",
  969                                           "connectionId=" + connectionId +
  970                         " unwrapping filter with target extended ClassLoader.");
  971   
  972                   filterValues[i] =
  973                       unwrap(filters[i], targetCl, defaultClassLoader,
  974                              NotificationFilter.class);
  975   
  976                   if (debug) logger.debug("addNotificationListener"+
  977                                           "(ObjectName,NotificationFilter)",
  978                                           "connectionId=" + connectionId
  979                                           +", name=" + names[i]
  980                                           +", filter=" + filterValues[i]);
  981   
  982                   ids[i] = (Integer)
  983                       doPrivilegedOperation(ADD_NOTIFICATION_LISTENERS,
  984                                             new Object[] { names[i],
  985                                                            filterValues[i] },
  986                                             sbjs[i]);
  987               }
  988   
  989               return ids;
  990           } catch (Exception e) {
  991               // remove all registered listeners
  992               for (int j=0; j<i; j++) {
  993                   try {
  994                       getServerNotifFwd().removeNotificationListener(names[j],
  995                                                                      ids[j]);
  996                   } catch (Exception eee) {
  997                       // strange
  998                   }
  999               }
 1000   
 1001               if (e instanceof PrivilegedActionException) {
 1002                   e = extractException(e);
 1003               }
 1004   
 1005               if (e instanceof ClassCastException) {
 1006                   throw (ClassCastException) e;
 1007               } else if (e instanceof IOException) {
 1008                   throw (IOException)e;
 1009               } else if (e instanceof InstanceNotFoundException) {
 1010                   throw (InstanceNotFoundException) e;
 1011               } else if (e instanceof RuntimeException) {
 1012                   throw (RuntimeException) e;
 1013               } else {
 1014                   throw newIOException("Got unexpected server exception: "+e,e);
 1015               }
 1016           }
 1017       }
 1018   
 1019       public void addNotificationListener(ObjectName name,
 1020                          ObjectName listener,
 1021                          MarshalledObject filter,
 1022                          MarshalledObject handback,
 1023                          Subject delegationSubject)
 1024           throws InstanceNotFoundException, IOException {
 1025   
 1026           checkNonNull("Target MBean name", name);
 1027           checkNonNull("Listener MBean name", listener);
 1028   
 1029           final NotificationFilter filterValue;
 1030           final Object handbackValue;
 1031           final boolean debug=logger.debugOn();
 1032   
 1033           final ClassLoader targetCl = getClassLoaderFor(name);
 1034   
 1035           if (debug) logger.debug("addNotificationListener"+
 1036                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1037                    "connectionId=" + connectionId
 1038                    +" unwrapping filter with target extended ClassLoader.");
 1039   
 1040           filterValue =
 1041               unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class);
 1042   
 1043           if (debug) logger.debug("addNotificationListener"+
 1044                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1045                    "connectionId=" + connectionId
 1046                    +" unwrapping handback with target extended ClassLoader.");
 1047   
 1048           handbackValue =
 1049               unwrap(handback, targetCl, defaultClassLoader, Object.class);
 1050   
 1051           try {
 1052               final Object params[] =
 1053                   new Object[] { name, listener, filterValue, handbackValue };
 1054   
 1055               if (debug) logger.debug("addNotificationListener"+
 1056                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1057                                "connectionId=" + connectionId
 1058                                +", name=" + name
 1059                                +", listenerName=" + listener
 1060                                +", filter=" + filterValue
 1061                                +", handback=" + handbackValue);
 1062   
 1063               doPrivilegedOperation(
 1064                 ADD_NOTIFICATION_LISTENER_OBJECTNAME,
 1065                 params,
 1066                 delegationSubject);
 1067           } catch (PrivilegedActionException pe) {
 1068               Exception e = extractException(pe);
 1069               if (e instanceof InstanceNotFoundException)
 1070                   throw (InstanceNotFoundException) e;
 1071               if (e instanceof IOException)
 1072                   throw (IOException) e;
 1073               throw newIOException("Got unexpected server exception: " + e, e);
 1074           }
 1075       }
 1076   
 1077       public void removeNotificationListeners(ObjectName name,
 1078                                               Integer[] listenerIDs,
 1079                                               Subject delegationSubject)
 1080           throws
 1081           InstanceNotFoundException,
 1082           ListenerNotFoundException,
 1083           IOException {
 1084   
 1085           if (name == null || listenerIDs == null)
 1086               throw new IllegalArgumentException("Illegal null parameter");
 1087   
 1088           for (int i = 0; i < listenerIDs.length; i++) {
 1089               if (listenerIDs[i] == null)
 1090                   throw new IllegalArgumentException("Null listener ID");
 1091           }
 1092   
 1093           try {
 1094               final Object params[] = new Object[] { name, listenerIDs };
 1095   
 1096               if (logger.debugOn()) logger.debug("removeNotificationListener"+
 1097                                      "(ObjectName,Integer[])",
 1098                                      "connectionId=" + connectionId
 1099                                      +", name=" + name
 1100                                      +", listenerIDs=" + objects(listenerIDs));
 1101   
 1102               doPrivilegedOperation(
 1103                 REMOVE_NOTIFICATION_LISTENER,
 1104                 params,
 1105                 delegationSubject);
 1106           } catch (PrivilegedActionException pe) {
 1107               Exception e = extractException(pe);
 1108               if (e instanceof InstanceNotFoundException)
 1109                   throw (InstanceNotFoundException) e;
 1110               if (e instanceof ListenerNotFoundException)
 1111                   throw (ListenerNotFoundException) e;
 1112               if (e instanceof IOException)
 1113                   throw (IOException) e;
 1114               throw newIOException("Got unexpected server exception: " + e, e);
 1115           }
 1116       }
 1117   
 1118       public void removeNotificationListener(ObjectName name,
 1119                                              ObjectName listener,
 1120                                              Subject delegationSubject)
 1121           throws
 1122           InstanceNotFoundException,
 1123           ListenerNotFoundException,
 1124           IOException {
 1125   
 1126           checkNonNull("Target MBean name", name);
 1127           checkNonNull("Listener MBean name", listener);
 1128   
 1129           try {
 1130               final Object params[] = new Object[] { name, listener };
 1131   
 1132               if (logger.debugOn()) logger.debug("removeNotificationListener"+
 1133                                      "(ObjectName,ObjectName)",
 1134                                      "connectionId=" + connectionId
 1135                                      +", name=" + name
 1136                                      +", listenerName=" + listener);
 1137   
 1138               doPrivilegedOperation(
 1139                 REMOVE_NOTIFICATION_LISTENER_OBJECTNAME,
 1140                 params,
 1141                 delegationSubject);
 1142           } catch (PrivilegedActionException pe) {
 1143               Exception e = extractException(pe);
 1144               if (e instanceof InstanceNotFoundException)
 1145                   throw (InstanceNotFoundException) e;
 1146               if (e instanceof ListenerNotFoundException)
 1147                   throw (ListenerNotFoundException) e;
 1148               if (e instanceof IOException)
 1149                   throw (IOException) e;
 1150               throw newIOException("Got unexpected server exception: " + e, e);
 1151           }
 1152       }
 1153   
 1154       public void removeNotificationListener(ObjectName name,
 1155                           ObjectName listener,
 1156                           MarshalledObject filter,
 1157                           MarshalledObject handback,
 1158                           Subject delegationSubject)
 1159           throws
 1160           InstanceNotFoundException,
 1161           ListenerNotFoundException,
 1162           IOException {
 1163   
 1164           checkNonNull("Target MBean name", name);
 1165           checkNonNull("Listener MBean name", listener);
 1166   
 1167           final NotificationFilter filterValue;
 1168           final Object handbackValue;
 1169           final boolean debug=logger.debugOn();
 1170   
 1171           final ClassLoader targetCl = getClassLoaderFor(name);
 1172   
 1173           if (debug) logger.debug("removeNotificationListener"+
 1174                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1175                    "connectionId=" + connectionId
 1176                    +" unwrapping filter with target extended ClassLoader.");
 1177   
 1178           filterValue =
 1179               unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class);
 1180   
 1181           if (debug) logger.debug("removeNotificationListener"+
 1182                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1183                    "connectionId=" + connectionId
 1184                    +" unwrapping handback with target extended ClassLoader.");
 1185   
 1186           handbackValue =
 1187               unwrap(handback, targetCl, defaultClassLoader, Object.class);
 1188   
 1189           try {
 1190               final Object params[] =
 1191                   new Object[] { name, listener, filterValue, handbackValue };
 1192   
 1193               if (debug) logger.debug("removeNotificationListener"+
 1194                    "(ObjectName,ObjectName,NotificationFilter,Object)",
 1195                                "connectionId=" + connectionId
 1196                                +", name=" + name
 1197                                +", listenerName=" + listener
 1198                                +", filter=" + filterValue
 1199                                +", handback=" + handbackValue);
 1200   
 1201               doPrivilegedOperation(
 1202                 REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK,
 1203                 params,
 1204                 delegationSubject);
 1205           } catch (PrivilegedActionException pe) {
 1206               Exception e = extractException(pe);
 1207               if (e instanceof InstanceNotFoundException)
 1208                   throw (InstanceNotFoundException) e;
 1209               if (e instanceof ListenerNotFoundException)
 1210                   throw (ListenerNotFoundException) e;
 1211               if (e instanceof IOException)
 1212                   throw (IOException) e;
 1213               throw newIOException("Got unexpected server exception: " + e, e);
 1214           }
 1215       }
 1216   
 1217       public NotificationResult fetchNotifications(long clientSequenceNumber,
 1218                                                    int maxNotifications,
 1219                                                    long timeout)
 1220           throws IOException {
 1221   
 1222           if (logger.debugOn()) logger.debug("fetchNotifications",
 1223                                  "connectionId=" + connectionId
 1224                                  +", timeout=" + timeout);
 1225   
 1226           if (maxNotifications < 0 || timeout < 0)
 1227               throw new IllegalArgumentException("Illegal negative argument");
 1228   
 1229           final boolean serverTerminated =
 1230               serverCommunicatorAdmin.reqIncoming();
 1231           try {
 1232               if (serverTerminated) {
 1233                   // we must not call fetchNotifs() if the server is
 1234                   // terminated (timeout elapsed).
 1235                   //
 1236                   return new NotificationResult(0L, 0L,
 1237                                                 new TargetedNotification[0]);
 1238   
 1239               }
 1240               final long csn = clientSequenceNumber;
 1241               final int mn = maxNotifications;
 1242               final long t = timeout;
 1243               PrivilegedAction<NotificationResult> action =
 1244                   new PrivilegedAction<NotificationResult>() {
 1245                       public NotificationResult run() {
 1246                           return getServerNotifFwd().fetchNotifs(csn, t, mn);
 1247                       }
 1248               };
 1249               if (acc == null)
 1250                   return action.run();
 1251               else
 1252                   return AccessController.doPrivileged(action, acc);
 1253           } finally {
 1254               serverCommunicatorAdmin.rspOutgoing();
 1255           }
 1256       }
 1257   
 1258       /**
 1259        * <p>Returns a string representation of this object.  In general,
 1260        * the <code>toString</code> method returns a string that
 1261        * "textually represents" this object. The result should be a
 1262        * concise but informative representation that is easy for a
 1263        * person to read.</p>
 1264        *
 1265        * @return a String representation of this object.
 1266        **/
 1267       public String toString() {
 1268           return super.toString() + ": connectionId=" + connectionId;
 1269       }
 1270   
 1271       //------------------------------------------------------------------------
 1272       // private classes
 1273       //------------------------------------------------------------------------
 1274   
 1275       private class PrivilegedOperation
 1276               implements PrivilegedExceptionAction<Object> {
 1277   
 1278           public PrivilegedOperation(int operation, Object[] params) {
 1279               this.operation = operation;
 1280               this.params = params;
 1281           }
 1282   
 1283           public Object run() throws Exception {
 1284               return doOperation(operation, params);
 1285           }
 1286   
 1287           private int operation;
 1288           private Object[] params;
 1289       }
 1290   
 1291       //------------------------------------------------------------------------
 1292       // private classes
 1293       //------------------------------------------------------------------------
 1294       private class RMIServerCommunicatorAdmin extends ServerCommunicatorAdmin {
 1295           public RMIServerCommunicatorAdmin(long timeout) {
 1296               super(timeout);
 1297           }
 1298   
 1299           protected void doStop() {
 1300               try {
 1301                   close();
 1302               } catch (IOException ie) {
 1303                   logger.warning("RMIServerCommunicatorAdmin-doStop",
 1304                                  "Failed to close: " + ie);
 1305                   logger.debug("RMIServerCommunicatorAdmin-doStop",ie);
 1306               }
 1307           }
 1308   
 1309       }
 1310   
 1311   
 1312       //------------------------------------------------------------------------
 1313       // private methods
 1314       //------------------------------------------------------------------------
 1315   
 1316       private ClassLoaderRepository getClassLoaderRepository() {
 1317           return
 1318               AccessController.doPrivileged(
 1319                   new PrivilegedAction<ClassLoaderRepository>() {
 1320                       public ClassLoaderRepository run() {
 1321                           return mbeanServer.getClassLoaderRepository();
 1322                       }
 1323                   });
 1324       }
 1325   
 1326       private ClassLoader getClassLoader(final ObjectName name)
 1327           throws InstanceNotFoundException {
 1328           try {
 1329               return
 1330                   AccessController.doPrivileged(
 1331                       new PrivilegedExceptionAction<ClassLoader>() {
 1332                           public ClassLoader run() throws InstanceNotFoundException {
 1333                               return mbeanServer.getClassLoader(name);
 1334                           }
 1335                       });
 1336           } catch (PrivilegedActionException pe) {
 1337               throw (InstanceNotFoundException) extractException(pe);
 1338           }
 1339       }
 1340   
 1341       private ClassLoader getClassLoaderFor(final ObjectName name)
 1342           throws InstanceNotFoundException {
 1343           try {
 1344               return (ClassLoader)
 1345                   AccessController.doPrivileged(
 1346                       new PrivilegedExceptionAction<Object>() {
 1347                           public Object run() throws InstanceNotFoundException {
 1348                               return mbeanServer.getClassLoaderFor(name);
 1349                           }
 1350                       });
 1351           } catch (PrivilegedActionException pe) {
 1352               throw (InstanceNotFoundException) extractException(pe);
 1353           }
 1354       }
 1355   
 1356       private Object doPrivilegedOperation(final int operation,
 1357                                            final Object[] params,
 1358                                            final Subject delegationSubject)
 1359           throws PrivilegedActionException, IOException {
 1360   
 1361           serverCommunicatorAdmin.reqIncoming();
 1362           try {
 1363   
 1364               final AccessControlContext reqACC;
 1365               if (delegationSubject == null)
 1366                   reqACC = acc;
 1367               else {
 1368                   if (subject == null) {
 1369                       final String msg =
 1370                           "Subject delegation cannot be enabled unless " +
 1371                           "an authenticated subject is put in place";
 1372                       throw new SecurityException(msg);
 1373                   }
 1374                   reqACC = subjectDelegator.delegatedContext(
 1375                       acc, delegationSubject, removeCallerContext);
 1376               }
 1377   
 1378               PrivilegedOperation op =
 1379                   new PrivilegedOperation(operation, params);
 1380               if (reqACC == null) {
 1381                   try {
 1382                       return op.run();
 1383                   } catch (Exception e) {
 1384                       if (e instanceof RuntimeException)
 1385                           throw (RuntimeException) e;
 1386                       throw new PrivilegedActionException(e);
 1387                   }
 1388               } else {
 1389                   return AccessController.doPrivileged(op, reqACC);
 1390               }
 1391           } catch (Error e) {
 1392               throw new JMXServerErrorException(e.toString(),e);
 1393           } finally {
 1394               serverCommunicatorAdmin.rspOutgoing();
 1395           }
 1396       }
 1397   
 1398       private Object doOperation(int operation, Object[] params)
 1399           throws Exception {
 1400   
 1401           switch (operation) {
 1402   
 1403           case CREATE_MBEAN:
 1404               return mbeanServer.createMBean((String)params[0],
 1405                                              (ObjectName)params[1]);
 1406   
 1407           case CREATE_MBEAN_LOADER:
 1408               return mbeanServer.createMBean((String)params[0],
 1409                                              (ObjectName)params[1],
 1410                                              (ObjectName)params[2]);
 1411   
 1412           case CREATE_MBEAN_PARAMS:
 1413               return mbeanServer.createMBean((String)params[0],
 1414                                              (ObjectName)params[1],
 1415                                              (Object[])params[2],
 1416                                              (String[])params[3]);
 1417   
 1418           case CREATE_MBEAN_LOADER_PARAMS:
 1419               return mbeanServer.createMBean((String)params[0],
 1420                                              (ObjectName)params[1],
 1421                                              (ObjectName)params[2],
 1422                                              (Object[])params[3],
 1423                                              (String[])params[4]);
 1424   
 1425           case GET_ATTRIBUTE:
 1426               return mbeanServer.getAttribute((ObjectName)params[0],
 1427                                               (String)params[1]);
 1428   
 1429           case GET_ATTRIBUTES:
 1430               return mbeanServer.getAttributes((ObjectName)params[0],
 1431                                                (String[])params[1]);
 1432   
 1433           case GET_DEFAULT_DOMAIN:
 1434               return mbeanServer.getDefaultDomain();
 1435   
 1436           case GET_DOMAINS:
 1437               return mbeanServer.getDomains();
 1438   
 1439           case GET_MBEAN_COUNT:
 1440               return mbeanServer.getMBeanCount();
 1441   
 1442           case GET_MBEAN_INFO:
 1443               return mbeanServer.getMBeanInfo((ObjectName)params[0]);
 1444   
 1445           case GET_OBJECT_INSTANCE:
 1446               return mbeanServer.getObjectInstance((ObjectName)params[0]);
 1447   
 1448           case INVOKE:
 1449               return mbeanServer.invoke((ObjectName)params[0],
 1450                                         (String)params[1],
 1451                                         (Object[])params[2],
 1452                                         (String[])params[3]);
 1453   
 1454           case IS_INSTANCE_OF:
 1455               return mbeanServer.isInstanceOf((ObjectName)params[0],
 1456                                               (String)params[1])
 1457                   ? Boolean.TRUE : Boolean.FALSE;
 1458   
 1459           case IS_REGISTERED:
 1460               return mbeanServer.isRegistered((ObjectName)params[0])
 1461                   ? Boolean.TRUE : Boolean.FALSE;
 1462   
 1463           case QUERY_MBEANS:
 1464               return mbeanServer.queryMBeans((ObjectName)params[0],
 1465                                              (QueryExp)params[1]);
 1466   
 1467           case QUERY_NAMES:
 1468               return mbeanServer.queryNames((ObjectName)params[0],
 1469                                             (QueryExp)params[1]);
 1470   
 1471           case SET_ATTRIBUTE:
 1472               mbeanServer.setAttribute((ObjectName)params[0],
 1473                                        (Attribute)params[1]);
 1474               return null;
 1475   
 1476           case SET_ATTRIBUTES:
 1477               return mbeanServer.setAttributes((ObjectName)params[0],
 1478                                                (AttributeList)params[1]);
 1479   
 1480           case UNREGISTER_MBEAN:
 1481               mbeanServer.unregisterMBean((ObjectName)params[0]);
 1482               return null;
 1483   
 1484           case ADD_NOTIFICATION_LISTENERS:
 1485               return getServerNotifFwd().addNotificationListener(
 1486                                                   (ObjectName)params[0],
 1487                                                   (NotificationFilter)params[1]);
 1488   
 1489           case ADD_NOTIFICATION_LISTENER_OBJECTNAME:
 1490               mbeanServer.addNotificationListener((ObjectName)params[0],
 1491                                                   (ObjectName)params[1],
 1492                                                   (NotificationFilter)params[2],
 1493                                                   params[3]);
 1494               return null;
 1495   
 1496           case REMOVE_NOTIFICATION_LISTENER:
 1497               getServerNotifFwd().removeNotificationListener(
 1498                                                      (ObjectName)params[0],
 1499                                                      (Integer[])params[1]);
 1500               return null;
 1501   
 1502           case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME:
 1503               mbeanServer.removeNotificationListener((ObjectName)params[0],
 1504                                                      (ObjectName)params[1]);
 1505               return null;
 1506   
 1507           case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK:
 1508               mbeanServer.removeNotificationListener(
 1509                                             (ObjectName)params[0],
 1510                                             (ObjectName)params[1],
 1511                                             (NotificationFilter)params[2],
 1512                                             params[3]);
 1513               return null;
 1514   
 1515           default:
 1516               throw new IllegalArgumentException("Invalid operation");
 1517           }
 1518       }
 1519   
 1520       private static <T> T unwrap(final MarshalledObject mo,
 1521                                   final ClassLoader cl,
 1522                                   final Class<T> wrappedClass)
 1523               throws IOException {
 1524           if (mo == null) {
 1525               return null;
 1526           }
 1527           try {
 1528               return AccessController.doPrivileged(
 1529                   new PrivilegedExceptionAction<T>() {
 1530                       public T run()
 1531                               throws IOException {
 1532                           final ClassLoader old =
 1533                               Thread.currentThread().getContextClassLoader();
 1534                           Thread.currentThread().setContextClassLoader(cl);
 1535                           try {
 1536                               return wrappedClass.cast(mo.get());
 1537                           } catch (ClassNotFoundException cnfe) {
 1538                               throw new UnmarshalException(cnfe.toString(), cnfe);
 1539                           } finally {
 1540                               Thread.currentThread().setContextClassLoader(old);
 1541                           }
 1542                       }
 1543                   });
 1544           } catch (PrivilegedActionException pe) {
 1545               Exception e = extractException(pe);
 1546               if (e instanceof IOException) {
 1547                   throw (IOException) e;
 1548               }
 1549               if (e instanceof ClassNotFoundException) {
 1550                   throw new UnmarshalException(e.toString(), e);
 1551               }
 1552               logger.warning("unwrap", "Failed to unmarshall object: " + e);
 1553               logger.debug("unwrap", e);
 1554           }
 1555           return null;
 1556       }
 1557   
 1558       private static <T> T unwrap(final MarshalledObject mo,
 1559                                   final ClassLoader cl1,
 1560                                   final ClassLoader cl2,
 1561                                   final Class<T> wrappedClass)
 1562           throws IOException {
 1563           if (mo == null) {
 1564               return null;
 1565           }
 1566           try {
 1567               return AccessController.doPrivileged(
 1568                      new PrivilegedExceptionAction<T>() {
 1569                          public T run()
 1570                              throws IOException {
 1571                              return unwrap(mo, new OrderClassLoaders(cl1, cl2),
 1572                                            wrappedClass);
 1573                          }
 1574                      });
 1575           } catch (PrivilegedActionException pe) {
 1576               Exception e = extractException(pe);
 1577               if (e instanceof IOException) {
 1578                   throw (IOException) e;
 1579               }
 1580               if (e instanceof ClassNotFoundException) {
 1581                   throw new UnmarshalException(e.toString(), e);
 1582               }
 1583               logger.warning("unwrap", "Failed to unmarshall object: " + e);
 1584               logger.debug("unwrap", e);
 1585           }
 1586           return null;
 1587       }
 1588   
 1589       /**
 1590        * Construct a new IOException with a nested exception.
 1591        * The nested exception is set only if JDK >= 1.4
 1592        */
 1593       private static IOException newIOException(String message,
 1594                                                 Throwable cause) {
 1595           final IOException x = new IOException(message);
 1596           return EnvHelp.initCause(x,cause);
 1597       }
 1598   
 1599       /**
 1600        * Iterate until we extract the real exception
 1601        * from a stack of PrivilegedActionExceptions.
 1602        */
 1603       private static Exception extractException(Exception e) {
 1604           while (e instanceof PrivilegedActionException) {
 1605               e = ((PrivilegedActionException)e).getException();
 1606           }
 1607           return e;
 1608       }
 1609   
 1610       private static final Object[] NO_OBJECTS = new Object[0];
 1611       private static final String[] NO_STRINGS = new String[0];
 1612   
 1613       /*
 1614        * The JMX spec doesn't explicitly say that a null Object[] or
 1615        * String[] in e.g. MBeanServer.invoke is equivalent to an empty
 1616        * array, but the RI behaves that way.  In the interests of
 1617        * maximal interoperability, we make it so even when we're
 1618        * connected to some other JMX implementation that might not do
 1619        * that.  This should be clarified in the next version of JMX.
 1620        */
 1621       private static Object[] nullIsEmpty(Object[] array) {
 1622           return (array == null) ? NO_OBJECTS : array;
 1623       }
 1624   
 1625       private static String[] nullIsEmpty(String[] array) {
 1626           return (array == null) ? NO_STRINGS : array;
 1627       }
 1628   
 1629       /*
 1630        * Similarly, the JMX spec says for some but not all methods in
 1631        * MBeanServer that take an ObjectName target, that if it's null
 1632        * you get this exception.  We specify it for all of them, and
 1633        * make it so for the ones where it's not specified in JMX even if
 1634        * the JMX implementation doesn't do so.
 1635        */
 1636       private static void checkNonNull(String what, Object x) {
 1637           if (x == null) {
 1638               RuntimeException wrapped =
 1639                   new IllegalArgumentException(what + " must not be null");
 1640               throw new RuntimeOperationsException(wrapped);
 1641           }
 1642       }
 1643   
 1644       //------------------------------------------------------------------------
 1645       // private variables
 1646       //------------------------------------------------------------------------
 1647   
 1648       private final Subject subject;
 1649   
 1650       private final SubjectDelegator subjectDelegator;
 1651   
 1652       private final boolean removeCallerContext;
 1653   
 1654       private final AccessControlContext acc;
 1655   
 1656       private final RMIServerImpl rmiServer;
 1657   
 1658       private final MBeanServer mbeanServer;
 1659   
 1660       private final ClassLoader defaultClassLoader;
 1661   
 1662       private final ClassLoaderWithRepository classLoaderWithRepository;
 1663   
 1664       private boolean terminated = false;
 1665   
 1666       private final String connectionId;
 1667   
 1668       private final ServerCommunicatorAdmin serverCommunicatorAdmin;
 1669   
 1670       // Method IDs for doOperation
 1671       //---------------------------
 1672   
 1673       private final static int
 1674           ADD_NOTIFICATION_LISTENERS                              = 1;
 1675       private final static int
 1676           ADD_NOTIFICATION_LISTENER_OBJECTNAME                    = 2;
 1677       private final static int
 1678           CREATE_MBEAN                                            = 3;
 1679       private final static int
 1680           CREATE_MBEAN_PARAMS                                     = 4;
 1681       private final static int
 1682           CREATE_MBEAN_LOADER                                     = 5;
 1683       private final static int
 1684           CREATE_MBEAN_LOADER_PARAMS                              = 6;
 1685       private final static int
 1686           GET_ATTRIBUTE                                           = 7;
 1687       private final static int
 1688           GET_ATTRIBUTES                                          = 8;
 1689       private final static int
 1690           GET_DEFAULT_DOMAIN                                      = 9;
 1691       private final static int
 1692           GET_DOMAINS                                             = 10;
 1693       private final static int
 1694           GET_MBEAN_COUNT                                         = 11;
 1695       private final static int
 1696           GET_MBEAN_INFO                                          = 12;
 1697       private final static int
 1698           GET_OBJECT_INSTANCE                                     = 13;
 1699       private final static int
 1700           INVOKE                                                  = 14;
 1701       private final static int
 1702           IS_INSTANCE_OF                                          = 15;
 1703       private final static int
 1704           IS_REGISTERED                                           = 16;
 1705       private final static int
 1706           QUERY_MBEANS                                            = 17;
 1707       private final static int
 1708           QUERY_NAMES                                             = 18;
 1709       private final static int
 1710           REMOVE_NOTIFICATION_LISTENER                            = 19;
 1711       private final static int
 1712           REMOVE_NOTIFICATION_LISTENER_FILTER_HANDBACK            = 20;
 1713       private final static int
 1714           REMOVE_NOTIFICATION_LISTENER_OBJECTNAME                 = 21;
 1715       private final static int
 1716           REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK = 22;
 1717       private final static int
 1718           SET_ATTRIBUTE                                           = 23;
 1719       private final static int
 1720           SET_ATTRIBUTES                                          = 24;
 1721       private final static int
 1722           UNREGISTER_MBEAN                                        = 25;
 1723   
 1724       // SERVER NOTIFICATION
 1725       //--------------------
 1726   
 1727       private ServerNotifForwarder serverNotifForwarder;
 1728       private Map env;
 1729   
 1730       // TRACES & DEBUG
 1731       //---------------
 1732   
 1733       private static String objects(final Object[] objs) {
 1734           if (objs == null)
 1735               return "null";
 1736           else
 1737               return Arrays.asList(objs).toString();
 1738       }
 1739   
 1740       private static String strings(final String[] strs) {
 1741           return objects(strs);
 1742       }
 1743   
 1744       private static final ClassLogger logger =
 1745           new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl");
 1746   }

Save This Page
Home » openjdk-7 » javax » management » remote » rmi » [javadoc | source]