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

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

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