jdk/test/javax/management/namespace/JMXNamespaceViewTest.java
changeset 1156 bbc2d15aaf7a
child 1227 4546977d0d66
equal deleted inserted replaced
1155:a9a142fcf1b5 1156:bbc2d15aaf7a
       
     1 /*
       
     2  * Copyright 2008 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 /*
       
    24  *
       
    25  * @test JMXNamespaceViewTest.java
       
    26  * @summary Test the JMXNamespaceView class.
       
    27  * @author Daniel Fuchs
       
    28  * @run clean JMXNamespaceViewTest Wombat WombatMBean
       
    29  * @run build JMXNamespaceViewTest Wombat WombatMBean
       
    30  * @run main JMXNamespaceViewTest
       
    31  */
       
    32 
       
    33 
       
    34 import java.lang.management.ManagementFactory;
       
    35 import java.net.ServerSocket;
       
    36 import java.rmi.registry.LocateRegistry;
       
    37 import java.util.ArrayList;
       
    38 import java.util.Arrays;
       
    39 import java.util.HashMap;
       
    40 import java.util.HashSet;
       
    41 import java.util.List;
       
    42 import java.util.Map;
       
    43 import java.util.Set;
       
    44 import javax.management.JMException;
       
    45 import javax.management.MBeanRegistration;
       
    46 import javax.management.MBeanServer;
       
    47 import javax.management.MBeanServerFactory;
       
    48 import javax.management.ObjectInstance;
       
    49 import javax.management.ObjectName;
       
    50 import javax.management.namespace.JMXNamespace;
       
    51 import javax.management.namespace.JMXNamespaceView;
       
    52 import javax.management.namespace.JMXNamespaces;
       
    53 import javax.management.namespace.JMXRemoteNamespace;
       
    54 import javax.management.remote.JMXConnectorServer;
       
    55 import javax.management.remote.JMXConnectorServerFactory;
       
    56 import javax.management.remote.JMXServiceURL;
       
    57 
       
    58 /**
       
    59  * A simple test to test the JMXNamespaceViewTest...
       
    60  * @author dfuchs
       
    61  */
       
    62 public class JMXNamespaceViewTest {
       
    63 
       
    64     // TODO: Remove this when contexts are added.
       
    65     public static class ClientContext {
       
    66         public final static String NAMESPACE = "jmx.context";
       
    67     }
       
    68 
       
    69     /**
       
    70      * Describe the configuration of a namespace
       
    71      */
       
    72     public static class NamespaceConfig {
       
    73         /** name of the namespace - no // allowed **/
       
    74         public String name;
       
    75         /**
       
    76          * JMXServiceURL through which the namespace is exported, if it
       
    77          * is a remote namespace. {@code null} if the namespace is local.
       
    78          * This is an inpur URL - eg: new JMXServiceURL("rmi",null,0).toString()
       
    79          * is acceptable here.
       
    80          */
       
    81         public String jmxurl;
       
    82         /**
       
    83          * Values of the name= key for each WombatMBean contained in the
       
    84          * namespace.
       
    85          */
       
    86         public String[] wombats;
       
    87         /** list of child namespace **/
       
    88         public NamespaceConfig[] children;
       
    89     }
       
    90 
       
    91     /**
       
    92      * Creates a NamespaceConfig record for a local namespace.
       
    93      * @param name     name  of the namespace
       
    94      * @param wombats  names of WombatMBean it should contain.
       
    95      * @return a NamespaceConfig.
       
    96      */
       
    97     public static NamespaceConfig config(String name, String[] wombats) {
       
    98         return config(name,null,wombats);
       
    99     }
       
   100 
       
   101     /**
       
   102      * Creates a NamespaceConfig record for a remote namespace.
       
   103      * @param name    name  of the namespace
       
   104      * @param jmxurl  input JMXServiceURL for creating the JMXConnectorServer
       
   105      * @param wombats names of WombatMBean it should contain.
       
   106      * @return a NamespaceConfig.
       
   107      */
       
   108     public static NamespaceConfig config(String name, String jmxurl,
       
   109             String[] wombats) {
       
   110         return config(name,jmxurl,wombats,(NamespaceConfig[])null);
       
   111     }
       
   112 
       
   113     /**
       
   114      * Creates a NamespaceConfig record for a local namespace.
       
   115      * @param name     name  of the namespace
       
   116      * @param wombats  names of WombatMBean it should contain.
       
   117      * @param children list  of sub namespaces.
       
   118      * @return a NamespaceConfig.
       
   119      */
       
   120     public static NamespaceConfig config(String name, String[] wombats,
       
   121             NamespaceConfig... children) {
       
   122         return config(name,null,wombats,children);
       
   123     }
       
   124 
       
   125     /**
       
   126      * Creates a NamespaceConfig record for a remote namespace.
       
   127      * @param name    name  of the namespace
       
   128      * @param jmxurl  input JMXServiceURL for creating the JMXConnectorServer
       
   129      * @param wombats names of WombatMBean it should contain.
       
   130      * @param children list  of sub namespaces.
       
   131      * @return a NamespaceConfig.
       
   132      */
       
   133     static NamespaceConfig config(String name, String jmxurl, String[] wombats,
       
   134             NamespaceConfig... children) {
       
   135          final NamespaceConfig cfg = new NamespaceConfig();
       
   136          cfg.name=name; cfg.jmxurl=jmxurl; cfg.wombats=wombats;
       
   137          cfg.children=children;
       
   138          return cfg;
       
   139     }
       
   140 
       
   141     /**
       
   142      * Returns the given names. This is a utility method to ease code
       
   143      * reading.
       
   144      * @param names names of Wombat MBeans.
       
   145      * @return the given names.
       
   146      */
       
   147     static String[] wombats(String... names) {
       
   148         return names;
       
   149     }
       
   150 
       
   151     /**
       
   152      * Creates a JMXServiceURL string for the given protocol.
       
   153      * This is also a utility method to ease code reading.
       
   154      * @param protocol The protocol name (e.g. "rmi")
       
   155      * @return A JMXServiceURL string.
       
   156      * @throws Exception if creation of the JMXServiceURL fails.
       
   157      */
       
   158     static String url(String protocol) throws Exception {
       
   159         return new JMXServiceURL(protocol,null,0).toString();
       
   160     }
       
   161 
       
   162     /**
       
   163      * Creates a config for a hierarchy of namespaces, mixing local namespaces
       
   164      * and remote namespaces using the given protocol.
       
   165      * @param protocol The protocol that should be used for remote namespaces.
       
   166      * @return A namespace config hierarchy.
       
   167      * @throws java.lang.Exception
       
   168      */
       
   169     public static NamespaceConfig[] makeConfig(String protocol)
       
   170         throws Exception {
       
   171         final NamespaceConfig[] config = {
       
   172         // Top level namespace "top1" (local)
       
   173         config("top1",wombats("wchief","w1","w2","w3"),
       
   174                 // top1//local1
       
   175                 config("local1",wombats("wchief","ww1","ww2")),
       
   176                 // top1//local2
       
   177                 config("local2",wombats("wchief","ww4","ww5","ww6"),
       
   178                     // top1//local2//local3
       
   179                     config("local3",wombats("wchief","www1","www2")),
       
   180                     // top1//local2//rmi1
       
   181                     config("rmi1",url(protocol),wombats("wchief","www3","www4","www5"))),
       
   182                 // top1//rmi2
       
   183                 config("rmi2",url(protocol),wombats("wchief","ww7","ww8","ww9"),
       
   184                     // top1//rmi2//local4
       
   185                     config("local4",wombats("wchief","www6","www7")),
       
   186                     // top1//rmi2//rmi3
       
   187                     config("rmi3",url(protocol),wombats("wchief","www3","www4","www5"),
       
   188                         // top1//rmi2//rmi3//local5
       
   189                         config("local5",wombats("wchief","wwww1"))))),
       
   190         // Top level namespace "top2" (local)
       
   191         config("top2",wombats("wchief","w21","w22","w23"),
       
   192                 // top2//local21
       
   193                 config("local21",wombats("wchief","ww21","ww22")),
       
   194                 // top2//rmi22
       
   195                 config("rmi22",url(protocol),wombats("wchief","ww27","ww28","ww29"),
       
   196                     // top2//rmi22//local24
       
   197                     config("local24",wombats("wchief","www26","www27")),
       
   198                     // top2//rmi22//rmi23
       
   199                     config("rmi23",url(protocol),wombats("wchief","www23","www24","www25"),
       
   200                         // top2//rmi22//rmi23//local25
       
   201                         config("local25",wombats("wchief","wwww21"))))),
       
   202         // Top level namespace "top3" (remote)
       
   203         config("top3",url(protocol),wombats("wchief","w31","w32","w33"),
       
   204                 // top3//local31
       
   205                 config("local31",wombats("wchief","ww31","ww32")),
       
   206                 // top3//rmi32
       
   207                 config("rmi32",url(protocol),wombats("wchief","ww37","ww38","ww39"),
       
   208                     // top3//rmi32//local34
       
   209                     config("local34",wombats("wchief","www36","www37")),
       
   210                     // top3//rmi32//rmi33
       
   211                     config("rmi33",url(protocol),wombats("wchief","www33","www34","www35"),
       
   212                         // top3//rmi32//local35
       
   213                         config("local35",wombats("wchief","wwww31"))))),
       
   214         };
       
   215         return config;
       
   216     }
       
   217 
       
   218     /**
       
   219      * Close all connector servers in the list.
       
   220      * @param cslist List of connector servers to close.
       
   221      */
       
   222     public static void closeAll(List<JMXConnectorServer> cslist) {
       
   223             for (JMXConnectorServer cs : cslist) {
       
   224                 try {
       
   225                     cs.stop();
       
   226                 } catch (Exception xx) {
       
   227                     System.err.println("Failed to stop connector: " + xx);
       
   228                 }
       
   229             }
       
   230     }
       
   231 
       
   232     public static class MBeanServerConfigCreator {
       
   233         public MBeanServer createMBeanServerFor(NamespaceConfig config) {
       
   234             return MBeanServerFactory.newMBeanServer();
       
   235         }
       
   236     }
       
   237 
       
   238     /**
       
   239      * Load the given namespace configuration inside the given MBeanServer.
       
   240      * Return a list of connector servers created in the process.
       
   241      * @param server      The MBeanServer in which the namespaces must
       
   242      *                    be created.
       
   243      * @param namespaces  The list of namespaces to create.
       
   244      * @return a list of started connector servers.
       
   245      * @throws java.lang.Exception failed to create the specified namespaces.
       
   246      */
       
   247     public static List<JMXConnectorServer> load(MBeanServer server,
       
   248            MBeanServerConfigCreator factory,
       
   249            NamespaceConfig... namespaces) throws Exception {
       
   250         final List<JMXConnectorServer> cslist =
       
   251                 new ArrayList<JMXConnectorServer>();
       
   252         try {
       
   253             final ObjectName creator =
       
   254                     new ObjectName("jmx.creator:type=JMXNamespaceCreator");
       
   255             if (System.getProperty("jmx.wait")!=null
       
   256                     && !server.isRegistered(creator)) {
       
   257                 server.registerMBean(new JMXNamespaceCreator(),creator);
       
   258             }
       
   259             for (NamespaceConfig cfg : namespaces) {
       
   260                 final MBeanServer srv = factory.createMBeanServerFor(cfg);
       
   261                 if (System.getProperty("jmx.wait")!=null
       
   262                     && !srv.isRegistered(creator)) {
       
   263                     srv.registerMBean(new JMXNamespaceCreator(),creator);
       
   264                 }
       
   265                 if (cfg.wombats != null) {
       
   266                     for (String w : cfg.wombats) {
       
   267                         final ObjectName n =
       
   268                                 new ObjectName("wombat:type=Wombat,name=" + w);
       
   269                         final WombatMBean ww = new Wombat();
       
   270                         srv.registerMBean(ww, n);
       
   271                     }
       
   272                 }
       
   273                 if (cfg.children != null) {
       
   274                     cslist.addAll(load(srv, factory, cfg.children));
       
   275                 }
       
   276                 JMXNamespace nm;
       
   277                 if (cfg.jmxurl == null) {
       
   278                     nm = new JMXNamespace(srv);
       
   279                 } else {
       
   280                     JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL(cfg.jmxurl),
       
   281                             null, srv);
       
   282                     srv.registerMBean(cs,
       
   283                             new ObjectName("jmx.remote:type=JMXConnectorServer"));
       
   284                     cs.start();
       
   285                     cslist.add(cs);
       
   286                     nm = JMXRemoteNamespace.
       
   287                             newJMXRemoteNamespace(cs.getAddress(),
       
   288                             null);
       
   289                 }
       
   290                 server.registerMBean(nm,
       
   291                         JMXNamespaces.getNamespaceObjectName(cfg.name));
       
   292                 if (nm instanceof JMXRemoteNamespace) {
       
   293                     server.invoke(
       
   294                             JMXNamespaces.getNamespaceObjectName(cfg.name),
       
   295                             "connect", null, null);
       
   296                 }
       
   297             }
       
   298         } catch (Exception x) {
       
   299             closeAll(cslist);
       
   300             throw x;
       
   301         }
       
   302         return cslist;
       
   303     }
       
   304 
       
   305     /**
       
   306      * Add an entry {@code <path,NamespaceConfig>} in the map for the given
       
   307      * namespace and its subnamespaces.
       
   308      * @param map    A {@code Map<path,NamespaceConfig>}.
       
   309      * @param parent The path of the parent workspace.
       
   310      * @param cfg    The NamespaceConfig hierarchy to index in the map.
       
   311      */
       
   312     public static void fillMap(Map<String,NamespaceConfig> map, String parent,
       
   313             NamespaceConfig cfg) {
       
   314 
       
   315         final String where;
       
   316         if (parent == null || parent.equals(""))
       
   317             where=cfg.name;
       
   318         else
       
   319             where=parent+JMXNamespaces.NAMESPACE_SEPARATOR+cfg.name;
       
   320         map.put(where,cfg);
       
   321         if (cfg.children==null) return;
       
   322         for(NamespaceConfig child:cfg.children) {
       
   323             fillMap(map,where,child);
       
   324         }
       
   325     }
       
   326 
       
   327     /**
       
   328      * Compare a list of namespace names obtained from JMXNamespaceView.list()
       
   329      * with the expected clildren list of the corresponding NamespaceConfig.
       
   330      * @param list      A list of namespace names
       
   331      * @param children  A list of NamespaceConfig correspondng to expected
       
   332      *                  namespace.
       
   333      * @param fail      If true and the comparison yields false, throws an
       
   334      *                  exception instead of simply returning false.
       
   335      * @return true if OK, false if NOK.
       
   336      */
       
   337     private static boolean compare(String[] list, NamespaceConfig[] children,
       
   338             boolean fail) {
       
   339         final List<String> found = new ArrayList<String>(Arrays.asList(list));
       
   340         if (found.contains(ClientContext.NAMESPACE))
       
   341             found.remove(ClientContext.NAMESPACE);
       
   342 
       
   343         if (children == null && found.size()==0) return  true;
       
   344         if (children == null && fail == false) return false;
       
   345         if (children == null) throw new RuntimeException(
       
   346                 "No child expected. Found "+Arrays.toString(list));
       
   347         final Set<String> names = new HashSet<String>();
       
   348         for (NamespaceConfig cfg : children) {
       
   349             names.add(cfg.name);
       
   350             if (found.contains(cfg.name)) continue;
       
   351             if (!fail) return false;
       
   352             throw new RuntimeException(cfg.name+" not found in "+
       
   353                     found);
       
   354         }
       
   355         found.removeAll(names);
       
   356         if (found.size()==0) return true;
       
   357         if (fail==false) return false;
       
   358         throw new RuntimeException("found additional namespaces: "+
       
   359                 found);
       
   360     }
       
   361 
       
   362     /**
       
   363      * Compares the result of queryNames(null,null) with a set of expected
       
   364      * wombats.
       
   365      * @param where    The path of the namespace that was queried.
       
   366      * @param list     The set of ObjectNames found.
       
   367      * @param wombats  The expected list of wombats.
       
   368      * @param fail      If true and the comparison yields false, throws an
       
   369      *                  exception instead of simply returning false.
       
   370      * @return true if OK, false if NOK.
       
   371      * @throws java.lang.Exception something went wrong.
       
   372      */
       
   373     private static boolean compare(String where,
       
   374             Set<ObjectName>list, String[] wombats,
       
   375             boolean fail) throws Exception {
       
   376         final Set<ObjectName> found = new HashSet<ObjectName>();
       
   377         final Set<ObjectName> expected = new HashSet<ObjectName>();
       
   378         for (ObjectName n : list) {
       
   379             if ("Wombat".equals(n.getKeyProperty("type")))
       
   380                found.add(n);
       
   381         }
       
   382         for(String w : wombats) {
       
   383             final ObjectName n =
       
   384                     new ObjectName("wombat:type=Wombat,name=" + w);
       
   385             expected.add(n);
       
   386             if (found.contains(n)) continue;
       
   387             if (fail == false) return false;
       
   388             throw new RuntimeException(where+
       
   389                     ": Wombat "+w+" not found in "+found);
       
   390         }
       
   391         found.removeAll(expected);
       
   392         if (found.size()==0) {
       
   393             System.out.println(where+": found all expected: "+expected);
       
   394             return true;
       
   395         }
       
   396         if (fail==false) return false;
       
   397         throw new RuntimeException(where+": found additional MBeans: "+
       
   398                 found);
       
   399     }
       
   400 
       
   401     /**
       
   402      * A generic test to test JMXNamespaceView over a namespace configuration.
       
   403      * @param server      The MBeanServer in which to load the namespace
       
   404      *                    config.
       
   405      * @param namespaces  The namespace config to run the test over...
       
   406      * @throws java.lang.Exception
       
   407      */
       
   408     public static void doTest(MBeanServer server, NamespaceConfig... namespaces)
       
   409             throws Exception {
       
   410         List<JMXConnectorServer> cslist = load(server,
       
   411                 new MBeanServerConfigCreator(), namespaces);
       
   412         Map<String,NamespaceConfig> inputMap =
       
   413                 new HashMap<String,NamespaceConfig>();
       
   414 
       
   415         for (NamespaceConfig cfg : namespaces) {
       
   416             fillMap(inputMap,"",cfg);
       
   417         }
       
   418         try {
       
   419             final JMXNamespaceView root = new JMXNamespaceView(server);
       
   420             List<JMXNamespaceView> vlist = new ArrayList<JMXNamespaceView>();
       
   421             vlist.add(root);
       
   422 
       
   423             while (!vlist.isEmpty()) {
       
   424                 JMXNamespaceView v = vlist.remove(0);
       
   425                 final String where = v.isRoot()?"root":v.where();
       
   426                 System.out.println(where+": "+
       
   427                    v.getMBeanServerConnection().queryNames(null,null));
       
   428                 for (String ns : v.list()) {
       
   429                     final JMXNamespaceView down = v.down(ns);
       
   430                     vlist.add(down);
       
   431                     if (!down.where().equals(v.isRoot()?ns:where+
       
   432                             JMXNamespaces.NAMESPACE_SEPARATOR+ns)) {
       
   433                         throw new RuntimeException("path of "+down.where()+
       
   434                             " should be "+(v.isRoot()?ns:where+
       
   435                             JMXNamespaces.NAMESPACE_SEPARATOR+ns));
       
   436                     }
       
   437                     if (down.up().equals(v)) continue;
       
   438                     throw new RuntimeException("parent of "+down.where()+
       
   439                             " should be "+where);
       
   440                 }
       
   441                 final NamespaceConfig[] children;
       
   442                 final NamespaceConfig   cfg;
       
   443                 if (v.isRoot()) {
       
   444                     children=namespaces;
       
   445                     cfg = null;
       
   446                 } else {
       
   447                     cfg = inputMap.get(where);
       
   448                     children = cfg==null?null:cfg.children;
       
   449                 }
       
   450                 compare(v.list(),children,true);
       
   451                 if (!v.isRoot()) {
       
   452                     if (where.endsWith(ClientContext.NAMESPACE)) {
       
   453                         System.out.println(where+": skipping queryNames analysis");
       
   454                         continue;
       
   455                     }
       
   456                     //System.out.println(where+": cfg is: "+cfg);
       
   457                     compare(where,v.getMBeanServerConnection().
       
   458                         queryNames(null, null),cfg.wombats,true);
       
   459                 }
       
   460             }
       
   461 
       
   462             exportAndWaitIfNeeded(server);
       
   463         } finally {
       
   464             closeAll(cslist);
       
   465         }
       
   466     }
       
   467 
       
   468     public static interface JMXNamespaceCreatorMBean {
       
   469         public ObjectInstance createLocalNamespace(String namespace)
       
   470                 throws JMException ;
       
   471         public void removeLocalNamespace(String namespace)
       
   472                 throws JMException;
       
   473     }
       
   474 
       
   475     public static class JMXNamespaceCreator
       
   476             implements MBeanRegistration,
       
   477                       JMXNamespaceCreatorMBean {
       
   478 
       
   479         private volatile MBeanServer mbeanServer;
       
   480 
       
   481         public ObjectInstance createLocalNamespace(String namespace)
       
   482             throws JMException {
       
   483             return mbeanServer.registerMBean(
       
   484                     new JMXNamespace(MBeanServerFactory.newMBeanServer()),
       
   485                     JMXNamespaces.getNamespaceObjectName(namespace));
       
   486         }
       
   487 
       
   488         public void removeLocalNamespace(String namespace)
       
   489             throws JMException {
       
   490             mbeanServer.unregisterMBean(
       
   491                     JMXNamespaces.getNamespaceObjectName(namespace));
       
   492         }
       
   493 
       
   494         public ObjectName preRegister(MBeanServer server, ObjectName name)
       
   495                 throws Exception {
       
   496             mbeanServer = server;
       
   497             return name;
       
   498         }
       
   499 
       
   500         public void postRegister(Boolean registrationDone) {
       
   501         }
       
   502 
       
   503         public void preDeregister() throws Exception {
       
   504          }
       
   505 
       
   506         public void postDeregister() {
       
   507         }
       
   508 
       
   509     }
       
   510 
       
   511     public static void exportAndWaitIfNeeded(MBeanServer server)
       
   512         throws Exception {
       
   513                 if (System.getProperty("jmx.wait")!=null) {
       
   514                 final int port = getPortFor("rmi");
       
   515                 LocateRegistry.createRegistry(port);
       
   516                 final JMXServiceURL url =
       
   517                         new JMXServiceURL("rmi",null,port,
       
   518                         "/jndi/rmi://localhost:"+port+"/jmxrmi");
       
   519                 final JMXConnectorServer cs =
       
   520                         JMXConnectorServerFactory.
       
   521                         newJMXConnectorServer(url, null, server);
       
   522                 cs.start();
       
   523                 try {
       
   524                     System.out.println("RMI Server waiting at: "+cs.getAddress());
       
   525                     System.in.read();
       
   526                 } finally {
       
   527                     cs.stop();
       
   528                 }
       
   529             }
       
   530     }
       
   531 
       
   532     public static int getPortFor(String protocol) throws Exception {
       
   533         final int aport =
       
   534               Integer.valueOf(System.getProperty("jmx."+protocol+".port","0"));
       
   535         if (aport > 0) return aport;
       
   536         final ServerSocket s = new ServerSocket(0);
       
   537         try {
       
   538             final int port = s.getLocalPort();
       
   539             return port;
       
   540         } finally {
       
   541             s.close();
       
   542         }
       
   543     }
       
   544 
       
   545     public static void main(String[] args) throws Exception {
       
   546         doTest(ManagementFactory.getPlatformMBeanServer(),makeConfig("rmi"));
       
   547     }
       
   548 
       
   549 }