jdk/src/share/classes/javax/management/MBeanServerFactory.java
changeset 1156 bbc2d15aaf7a
parent 2 90ce3da70b43
child 1247 b4c26443dee5
equal deleted inserted replaced
1155:a9a142fcf1b5 1156:bbc2d15aaf7a
    23  * have any questions.
    23  * have any questions.
    24  */
    24  */
    25 
    25 
    26 package javax.management;
    26 package javax.management;
    27 
    27 
       
    28 import com.sun.jmx.defaults.JmxProperties;
    28 import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER;
    29 import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER;
    29 import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
    30 import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
    30 import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor;
       
    31 import com.sun.jmx.mbeanserver.GetPropertyAction;
    31 import com.sun.jmx.mbeanserver.GetPropertyAction;
       
    32 import com.sun.jmx.mbeanserver.Util;
    32 import java.security.AccessController;
    33 import java.security.AccessController;
    33 import java.security.Permission;
    34 import java.security.Permission;
    34 import java.util.ArrayList;
    35 import java.util.ArrayList;
       
    36 import java.util.List;
    35 import java.util.logging.Level;
    37 import java.util.logging.Level;
    36 import javax.management.loading.ClassLoaderRepository;
    38 import javax.management.loading.ClassLoaderRepository;
       
    39 
    37 
    40 
    38 /**
    41 /**
    39  * <p>Provides MBean server references.  There are no instances of
    42  * <p>Provides MBean server references.  There are no instances of
    40  * this class.</p>
    43  * this class.</p>
    41  *
    44  *
    78  *
    81  *
    79  * <p>The MBeanServerBuilder makes it possible to wrap the MBeanServers
    82  * <p>The MBeanServerBuilder makes it possible to wrap the MBeanServers
    80  * returned by the default MBeanServerBuilder implementation, for the purpose
    83  * returned by the default MBeanServerBuilder implementation, for the purpose
    81  * of e.g. adding an additional security layer.</p>
    84  * of e.g. adding an additional security layer.</p>
    82  *
    85  *
       
    86  * <p id="MBeanServerName">Since version 2.0 of the JMX API, when creating
       
    87  * an MBeanServer,
       
    88  * it is possible to specify an {@linkplain #getMBeanServerName
       
    89  * MBean Server name}.
       
    90  * To create an MBean Server with a name, the MBeanServerFactory provides two
       
    91  * new methods:</p>
       
    92  * <ul><li>{@link #createNamedMBeanServer
       
    93  * createNamedMBeanServer(mbeanServerName, defaultDomain)}: creates a named
       
    94  * MBeanServer and keeps an internal reference to the created object. The
       
    95  * MBeanServer can be later retrieved using {@link #findMBeanServer
       
    96  * findMBeanServer(mbeanServerId)} or
       
    97  * {@link #findMBeanServerByName findMBeanServerByName(mbeanServerName)}, and
       
    98  * can be released through {@link
       
    99  * #releaseMBeanServer releaseMBeanServer(mbeanServer)}.</li>
       
   100  * <li>{@link #newNamedMBeanServer
       
   101  * newNamedMBeanServer(mbeanServerName, defaultDomain)}:
       
   102  * creates a named MBeanServer without keeping any internal reference to the
       
   103  * named server.</li>
       
   104  * </ul>
       
   105  * <p>The name of the MBeanServer is stored in the
       
   106  * {@linkplain MBeanServerDelegate MBean Server delegate MBean}
       
   107  * and is embedded in its {@link MBeanServerDelegate#getMBeanServerId
       
   108  * MBeanServerId} attribute.</p>
       
   109  * <p>The name of the MBeanServer is particularly useful when
       
   110  * <a href="MBeanServer.html#security">MBean permissions</a> are checked:
       
   111  * it makes it
       
   112  * possible to distinguish between an MBean named "X" in MBeanServer named
       
   113  * "M1", and another MBean of the same name "X" in another MBeanServer named
       
   114  * "M2".</p>
       
   115  * <p>When naming MBean servers it is recommended to use a name that starts
       
   116  * with a Java package name. It is also recommended that the default domain and
       
   117  * the MBeanServer name be the same.</p>
       
   118  *
    83  * @since 1.5
   119  * @since 1.5
    84  */
   120  */
    85 public class MBeanServerFactory {
   121 public class MBeanServerFactory {
       
   122 
       
   123     /**
       
   124      * The <a href="#MBeanServerName">MBean Server name</a> that will be
       
   125      * checked by a <a href="MBeanServer.html#security">permission you need</a>
       
   126      * when checking access to an MBean registered in an MBeanServer for
       
   127      * which no MBeanServer name was specified.
       
   128      *
       
   129      * @since 1.7
       
   130      */
       
   131     public final static String DEFAULT_MBEANSERVER_NAME = "default";
    86 
   132 
    87     /*
   133     /*
    88      * There are no instances of this class so don't generate the
   134      * There are no instances of this class so don't generate the
    89      * default public constructor.
   135      * default public constructor.
    90      */
   136      */
   220      *
   266      *
   221      * @exception ClassCastException if the property
   267      * @exception ClassCastException if the property
   222      * <code>javax.management.builder.initial</code> exists and can be
   268      * <code>javax.management.builder.initial</code> exists and can be
   223      * instantiated but is not assignment compatible with {@link
   269      * instantiated but is not assignment compatible with {@link
   224      * MBeanServerBuilder}.
   270      * MBeanServerBuilder}.
       
   271      *
       
   272      * @see #createNamedMBeanServer
   225      */
   273      */
   226     public static MBeanServer createMBeanServer(String domain)  {
   274     public static MBeanServer createMBeanServer(String domain)  {
   227         checkPermission("createMBeanServer");
   275         return createMBeanServer(null,domain);
   228 
   276     }
   229         final MBeanServer mBeanServer = newMBeanServer(domain);
   277 
   230         addMBeanServer(mBeanServer);
   278     /**
   231         return mBeanServer;
   279      * <p>Return a new object implementing the {@link MBeanServer}
   232     }
   280      * interface with the specified
   233 
   281      * <a href="#MBeanServerName">MBean Server name</a>
   234     /**
   282      * and default domain name. The given MBean server name
   235      * <p>Return a new object implementing the MBeanServer interface
   283      * is used in <a href="MBeanServer.html#security">security checks</a>, and
   236      * with a standard default domain name, without keeping an
   284      * can also be used to {@linkplain #findMBeanServerByName(java.lang.String)
   237      * internal reference to this new object.  The default domain name
   285      * find an MBeanServer by name}. The given
   238      * is used as the domain part in the ObjectName of MBeans when the
   286      * domain name is used as the domain part in the ObjectName of
   239      * domain is specified by the user is null.</p>
   287      * MBeans when the domain is specified by the user is null.</p>
   240      *
   288      *
   241      * <p>The standard default domain name is
   289      * <p>The MBeanServer reference is internally kept. This will
   242      * <code>DefaultDomain</code>.</p>
   290      * allow <CODE>findMBeanServer</CODE> to return a reference to
   243      *
   291      * this MBeanServer object.</p>
   244      * <p>No reference is kept. <CODE>findMBeanServer</CODE> will not
   292      *
   245      * be able to return a reference to this MBeanServer object, but
   293      * @param mbeanServerName the name for the created
   246      * the garbage collector will be able to remove the MBeanServer
   294      * MBeanServer.  This is the name that will be included in the
   247      * object when it is no longer referenced.</p>
   295      * {@linkplain MBeanPermission permission you need} when checking
   248      *
   296      * <a href="MBeanServer.html#security">MBean Permissions</a> for accessing
   249      * <p>This method is equivalent to <code>newMBeanServer(null)</code>.</p>
   297      * an MBean registered in the returned MBeanServer. The characters
       
   298      * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star)
       
   299      * and  {@code '?'} are not legal.
       
   300      * It is recommended that the {@code mbeanServerName}
       
   301      * be unique in the context of a JVM, and in the form of a java package
       
   302      * identifier. If {@code mbeanServerName} is {@code null} then the created
       
   303      * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used.
       
   304      * Calling {@code createNamedMBeanServer(null,domain)} is equivalent
       
   305      * to calling {@link #createMBeanServer(String) createMBeanServer(domain)}.
       
   306      *
       
   307      * @param domain the default domain name for the created
       
   308      * MBeanServer.  This is the value that will be returned by {@link
       
   309      * MBeanServer#getDefaultDomain}. If a non null mbeanServerName is given,
       
   310      * it is recommended to pass the same value as default domain.
   250      *
   311      *
   251      * @return the newly created MBeanServer.
   312      * @return the newly created MBeanServer.
   252      *
   313      *
   253      * @exception SecurityException if there is a SecurityManager and the
   314      * @exception SecurityException if there is a SecurityManager and
   254      * caller's permissions do not include or imply <code>{@link
   315      * the caller's permissions do not include or imply <code>{@link
   255      * MBeanServerPermission}("newMBeanServer")</code>.
   316      * MBeanServerPermission}("createMBeanServer")</code>.
   256      *
   317      *
   257      * @exception JMRuntimeException if the property
   318      * @exception JMRuntimeException if the property
   258      * <code>javax.management.builder.initial</code> exists but the
   319      * <code>javax.management.builder.initial</code> exists but the
   259      * class it names cannot be instantiated through a public
   320      * class it names cannot be instantiated through a public
   260      * no-argument constructor; or if the instantiated builder returns
   321      * no-argument constructor; or if the instantiated builder returns
   264      *
   325      *
   265      * @exception ClassCastException if the property
   326      * @exception ClassCastException if the property
   266      * <code>javax.management.builder.initial</code> exists and can be
   327      * <code>javax.management.builder.initial</code> exists and can be
   267      * instantiated but is not assignment compatible with {@link
   328      * instantiated but is not assignment compatible with {@link
   268      * MBeanServerBuilder}.
   329      * MBeanServerBuilder}.
   269      */
   330      *
   270     public static MBeanServer newMBeanServer() {
   331      * @exception IllegalArgumentException if the specified
   271         return newMBeanServer(null);
   332      * {@code mbeanServerName} is empty, or is {@code "-"}, or contains a
       
   333      * character which is not legal.
       
   334      *
       
   335      * @exception UnsupportedOperationException if the specified
       
   336      * {@code mbeanServerName} cannot be set.
       
   337      *
       
   338      * @since 1.7
       
   339      */
       
   340     public static MBeanServer createNamedMBeanServer(String mbeanServerName,
       
   341             String domain)  {
       
   342         return createMBeanServer(mbeanServerName, domain);
   272     }
   343     }
   273 
   344 
   274     /**
   345     /**
   275      * <p>Return a new object implementing the MBeanServer interface
   346      * <p>Return a new object implementing the MBeanServer interface
   276      * with the specified default domain name, without keeping an
   347      * with a standard default domain name, without keeping an
   277      * internal reference to this new object.  The given domain name
   348      * internal reference to this new object.  The default domain name
   278      * is used as the domain part in the ObjectName of MBeans when the
   349      * is used as the domain part in the ObjectName of MBeans when the
   279      * domain is specified by the user is null.</p>
   350      * domain is specified by the user is null.</p>
       
   351      *
       
   352      * <p>The standard default domain name is
       
   353      * <code>DefaultDomain</code>.</p>
   280      *
   354      *
   281      * <p>No reference is kept. <CODE>findMBeanServer</CODE> will not
   355      * <p>No reference is kept. <CODE>findMBeanServer</CODE> will not
   282      * be able to return a reference to this MBeanServer object, but
   356      * be able to return a reference to this MBeanServer object, but
   283      * the garbage collector will be able to remove the MBeanServer
   357      * the garbage collector will be able to remove the MBeanServer
   284      * object when it is no longer referenced.</p>
   358      * object when it is no longer referenced.</p>
   285      *
   359      *
   286      * @param domain the default domain name for the created
   360      * <p>This method is equivalent to <code>newMBeanServer(null)</code>.</p>
   287      * MBeanServer.  This is the value that will be returned by {@link
       
   288      * MBeanServer#getDefaultDomain}.
       
   289      *
   361      *
   290      * @return the newly created MBeanServer.
   362      * @return the newly created MBeanServer.
   291      *
   363      *
   292      * @exception SecurityException if there is a SecurityManager and the
   364      * @exception SecurityException if there is a SecurityManager and the
   293      * caller's permissions do not include or imply <code>{@link
   365      * caller's permissions do not include or imply <code>{@link
   304      * @exception ClassCastException if the property
   376      * @exception ClassCastException if the property
   305      * <code>javax.management.builder.initial</code> exists and can be
   377      * <code>javax.management.builder.initial</code> exists and can be
   306      * instantiated but is not assignment compatible with {@link
   378      * instantiated but is not assignment compatible with {@link
   307      * MBeanServerBuilder}.
   379      * MBeanServerBuilder}.
   308      */
   380      */
       
   381     public static MBeanServer newMBeanServer() {
       
   382         return newMBeanServer(null);
       
   383     }
       
   384 
       
   385     /**
       
   386      * <p>Return a new object implementing the MBeanServer interface
       
   387      * with the specified default domain name, without keeping an
       
   388      * internal reference to this new object.  The given domain name
       
   389      * is used as the domain part in the ObjectName of MBeans when the
       
   390      * domain is specified by the user is null.</p>
       
   391      *
       
   392      * <p>No reference is kept. <CODE>findMBeanServer</CODE> will not
       
   393      * be able to return a reference to this MBeanServer object, but
       
   394      * the garbage collector will be able to remove the MBeanServer
       
   395      * object when it is no longer referenced.</p>
       
   396      *
       
   397      * @param domain the default domain name for the created
       
   398      * MBeanServer.  This is the value that will be returned by {@link
       
   399      * MBeanServer#getDefaultDomain}.
       
   400      *
       
   401      * @return the newly created MBeanServer.
       
   402      *
       
   403      * @exception SecurityException if there is a SecurityManager and the
       
   404      * caller's permissions do not include or imply <code>{@link
       
   405      * MBeanServerPermission}("newMBeanServer")</code>.
       
   406      *
       
   407      * @exception JMRuntimeException if the property
       
   408      * <code>javax.management.builder.initial</code> exists but the
       
   409      * class it names cannot be instantiated through a public
       
   410      * no-argument constructor; or if the instantiated builder returns
       
   411      * null from its {@link MBeanServerBuilder#newMBeanServerDelegate
       
   412      * newMBeanServerDelegate} or {@link
       
   413      * MBeanServerBuilder#newMBeanServer newMBeanServer} methods.
       
   414      *
       
   415      * @exception ClassCastException if the property
       
   416      * <code>javax.management.builder.initial</code> exists and can be
       
   417      * instantiated but is not assignment compatible with {@link
       
   418      * MBeanServerBuilder}.
       
   419      */
   309     public static MBeanServer newMBeanServer(String domain)  {
   420     public static MBeanServer newMBeanServer(String domain)  {
       
   421         return newMBeanServer(null,domain);
       
   422     }
       
   423 
       
   424     /**
       
   425      * <p>Return a new object implementing the MBeanServer interface
       
   426      * with the specified <a href="#MBeanServerName">MBean server name</a>
       
   427      * and default domain name, without keeping an
       
   428      * internal reference to this new object.  The given MBean server name
       
   429      * is used in <a href="MBeanServer.html#security">security checks</a>.
       
   430      * The given domain name
       
   431      * is used as the domain part in the ObjectName of MBeans when the
       
   432      * domain is specified by the user is null.</p>
       
   433      *
       
   434      * <p>No reference is kept. <CODE>findMBeanServer</CODE> and
       
   435      * <CODE>findMBeanServerByName</CODE> will not
       
   436      * be able to return a reference to this MBeanServer object, but
       
   437      * the garbage collector will be able to remove the MBeanServer
       
   438      * object when it is no longer referenced.</p>
       
   439      *
       
   440      * @param mbeanServerName the name for the created
       
   441      * MBeanServer.  This is the name that will be included in the
       
   442      * {@linkplain MBeanPermission permission you need} when checking
       
   443      * <a href="MBeanServer.html#security">MBean Permissions</a> for accessing
       
   444      * an MBean registered in the returned MBeanServer. The characters
       
   445      * {@code ':'} (colon), {@code ';'} (semicolon), {@code '*'} (star)
       
   446      * and  {@code '?'} are not legal.
       
   447      * It is recommended that the mbeanServerName
       
   448      * be unique in the context of a JVM, and in the form of a java package
       
   449      * identifier. If {@code mbeanServerName} is {@code null} then the created
       
   450      * MBean Server has no name - and {@value #DEFAULT_MBEANSERVER_NAME} is used.
       
   451      * Calling {@code newNamedMBeanServer(null,domain)} is equivalent
       
   452      * to calling {@link #newMBeanServer(String) newMBeanServer(domain)}.
       
   453      *
       
   454      * @param domain the default domain name for the created
       
   455      * MBeanServer.  This is the value that will be returned by {@link
       
   456      * MBeanServer#getDefaultDomain}.
       
   457      *
       
   458      * @return the newly created MBeanServer.
       
   459      *
       
   460      * @exception SecurityException if there is a SecurityManager and the
       
   461      * caller's permissions do not include or imply <code>{@link
       
   462      * MBeanServerPermission}("newMBeanServer")</code>.
       
   463      *
       
   464      * @exception JMRuntimeException if the property
       
   465      * <code>javax.management.builder.initial</code> exists but the
       
   466      * class it names cannot be instantiated through a public
       
   467      * no-argument constructor; or if the instantiated builder returns
       
   468      * null from its {@link MBeanServerBuilder#newMBeanServerDelegate
       
   469      * newMBeanServerDelegate} or {@link
       
   470      * MBeanServerBuilder#newMBeanServer newMBeanServer} methods.
       
   471      *
       
   472      * @exception ClassCastException if the property
       
   473      * <code>javax.management.builder.initial</code> exists and can be
       
   474      * instantiated but is not assignment compatible with {@link
       
   475      * MBeanServerBuilder}.
       
   476      *
       
   477      * @exception IllegalArgumentException if the specified
       
   478      * {@code mbeanServerName} is empty, or is {@code "-"},
       
   479      * or contains a character which is not legal.
       
   480      *
       
   481      * @exception UnsupportedOperationException if the specified
       
   482      * {@code mbeanServerName} cannot be set.
       
   483      *
       
   484      * @since 1.7
       
   485      */
       
   486     public static MBeanServer newNamedMBeanServer(String mbeanServerName,
       
   487             String domain)  {
       
   488         return newMBeanServer(mbeanServerName, domain);
       
   489     }
       
   490 
       
   491     private static MBeanServer createMBeanServer(String mbeanServerName,
       
   492             String domain)  {
       
   493         checkPermission("createMBeanServer");
       
   494 
       
   495         final MBeanServer mBeanServer =
       
   496                 newMBeanServer(mbeanServerName,domain);
       
   497         addMBeanServer(mBeanServer);
       
   498         return mBeanServer;
       
   499     }
       
   500 
       
   501     private static MBeanServer newMBeanServer(String mbeanServerName,
       
   502             String domain) {
   310         checkPermission("newMBeanServer");
   503         checkPermission("newMBeanServer");
   311 
   504 
   312         // Get the builder. Creates a new one if necessary.
   505         // Get the builder. Creates a new one if necessary.
   313         //
   506         //
   314         final MBeanServerBuilder mbsBuilder = getNewMBeanServerBuilder();
   507         final MBeanServerBuilder mbsBuilder = getNewMBeanServerBuilder();
   315         // Returned value cannot be null.  NullPointerException if violated.
   508         // Returned value cannot be null.  NullPointerException if violated.
   316 
   509 
   317         synchronized(mbsBuilder) {
   510         synchronized(mbsBuilder) {
   318             final MBeanServerDelegate delegate  =
   511             final MBeanServerDelegate delegate  =
   319                 mbsBuilder.newMBeanServerDelegate();
   512                     mbsBuilder.newMBeanServerDelegate();
   320             if (delegate == null) {
   513             if (delegate == null) {
   321                 final String msg =
   514                 final String msg =
   322                     "MBeanServerBuilder.newMBeanServerDelegate() " +
   515                         "MBeanServerBuilder.newMBeanServerDelegate() " +
   323                     "returned null";
   516                         "returned null";
   324                 throw new JMRuntimeException(msg);
   517                 throw new JMRuntimeException(msg);
   325             }
   518             }
       
   519 
       
   520             // Sets the name on the delegate. For complex backward
       
   521             // compatibility reasons it is not possible to give the
       
   522             // name to the MBeanServerDelegate constructor.
       
   523             //
       
   524             // The method setMBeanServerName() will call getMBeanServerId()
       
   525             // to check that the name is accurately set in the MBeanServerId.
       
   526             // If not (which could happen if a custom MBeanServerDelegate
       
   527             // implementation overrides getMBeanServerId() and was not updated
       
   528             // with respect to JMX 2.0 spec, this method will throw an
       
   529             // IllegalStateException...
       
   530             //
       
   531             if (!Util.isMBeanServerNameUndefined(mbeanServerName)) {
       
   532                 delegate.setMBeanServerName(mbeanServerName);
       
   533             }
       
   534 
   326             final MBeanServer mbeanServer =
   535             final MBeanServer mbeanServer =
   327                 mbsBuilder.newMBeanServer(domain,null,delegate);
   536                     mbsBuilder.newMBeanServer(domain,null,delegate);
   328             if (mbeanServer == null) {
   537             if (mbeanServer == null) {
   329                 final String msg =
   538                 final String msg =
   330                     "MBeanServerBuilder.newMBeanServer() returned null";
   539                         "MBeanServerBuilder.newMBeanServer() returned null";
   331                 throw new JMRuntimeException(msg);
   540                 throw new JMRuntimeException(msg);
   332             }
   541             }
       
   542 
       
   543             // double check that the MBeanServer name is correctly set.
       
   544             // "*" might mean that the caller doesn't have the permission
       
   545             // to see the MBeanServer name.
       
   546             //
       
   547             final String mbsName = Util.getMBeanServerSecurityName(mbeanServer);
       
   548             if (!mbsName.equals(Util.checkServerName(mbeanServerName))
       
   549                 && !mbsName.equals("*")) {
       
   550                 throw new UnsupportedOperationException(
       
   551                         "can't create MBeanServer with name \""+
       
   552                         mbeanServerName+"\" using "+
       
   553                         builder.getClass().getName());
       
   554             }
       
   555 
   333             return mbeanServer;
   556             return mbeanServer;
   334         }
   557         }
   335     }
   558     }
   336 
   559 
   337     /**
   560     /**
   361         if (agentId == null)
   584         if (agentId == null)
   362             return new ArrayList<MBeanServer>(mBeanServerList);
   585             return new ArrayList<MBeanServer>(mBeanServerList);
   363 
   586 
   364         ArrayList<MBeanServer> result = new ArrayList<MBeanServer>();
   587         ArrayList<MBeanServer> result = new ArrayList<MBeanServer>();
   365         for (MBeanServer mbs : mBeanServerList) {
   588         for (MBeanServer mbs : mBeanServerList) {
   366             String name = mBeanServerName(mbs);
   589             String name = mBeanServerId(mbs);
   367             if (agentId.equals(name))
   590             if (agentId.equals(name))
   368                 result.add(mbs);
   591                 result.add(mbs);
   369         }
   592         }
   370         return result;
   593         return result;
   371     }
   594     }
   372 
   595 
   373     /**
   596     /**
       
   597      * <p>Returns a list of registered MBeanServer objects with the given name.  A
       
   598      * registered MBeanServer object is one that was created by one of
       
   599      * the <code>createMBeanServer</code> or <code>createNamedMBeanServer</code>
       
   600      * methods and not subsequently released with <code>releaseMBeanServer</code>.</p>
       
   601      * <p>See the section about <a href="#MBeanServerName">MBean Server names</a>
       
   602      * above.</p>
       
   603      *
       
   604      * @param mbeanServerName The name of the MBeanServer to
       
   605      * retrieve.  If this parameter is null, all registered MBeanServers
       
   606      * in this JVM are returned.
       
   607      * Otherwise, only those MBeanServers that have a name
       
   608      * matching <code>mbeanServerName</code> are returned: this
       
   609      * parameter can be a pattern, where {@code '*'} matches any
       
   610      * sequence of characters and {@code '?'} matches any character.<br>
       
   611      * The name of an MBeanServer, if specified, is embedded in the
       
   612      * <code>MBeanServerId</code> attribute of its delegate MBean:
       
   613      * this method will parse the <code>MBeanServerId</code> to get the
       
   614      * MBeanServer name. If this parameter is equal to {@code "*"} then
       
   615      * all registered MBeanServers in this JVM are returned, whether they have
       
   616      * a name or not: {@code findMBeanServerByName(null)},
       
   617      * {@code findMBeanServerByName("*")} and {@code findMBeanServer(null)},
       
   618      * are equivalent. It is also possible to get all MBeanServers for which
       
   619      * no name was specified by calling <code>findMBeanServerByName({@value
       
   620      * #DEFAULT_MBEANSERVER_NAME})</code>.
       
   621      *
       
   622      * @return A list of MBeanServer objects.
       
   623      *
       
   624      * @exception SecurityException if there is a SecurityManager and the
       
   625      * caller's permissions do not include or imply <code>{@link
       
   626      * MBeanServerPermission}("findMBeanServer")</code>.
       
   627      *
       
   628      * @see #getMBeanServerName(MBeanServer)
       
   629      * @since 1.7
       
   630      */
       
   631     public synchronized static
       
   632             List<MBeanServer> findMBeanServerByName(String mbeanServerName) {
       
   633 
       
   634         checkPermission("findMBeanServer");
       
   635 
       
   636         if (mbeanServerName==null || "*".equals(mbeanServerName))
       
   637             return new ArrayList<MBeanServer>(mBeanServerList);
       
   638 
       
   639         // noname=true iff we are looking for MBeanServers for which no name
       
   640         // were specified.
       
   641         ArrayList<MBeanServer> result = new ArrayList<MBeanServer>();
       
   642         for (MBeanServer mbs : mBeanServerList) {
       
   643             final String name = Util.getMBeanServerSecurityName(mbs);
       
   644             if (Util.wildmatch(name, mbeanServerName)) result.add(mbs);
       
   645         }
       
   646         return result;
       
   647     }
       
   648 
       
   649     /**
       
   650      * Returns the name of the MBeanServer embedded in the MBeanServerId of
       
   651      * the given {@code server}. If the given MBeanServerId doesn't contain
       
   652      * any name, {@value #DEFAULT_MBEANSERVER_NAME} is returned.
       
   653      * The MBeanServerId is expected to be of the form:
       
   654      * {@code *[;mbeanServerName=<mbeanServerName>[;*]]}
       
   655      * <br>where {@code *} denotes any sequence of characters, and {@code [ ]}
       
   656      * indicate optional parts.
       
   657      * </p>
       
   658      * <p>For instance, if an MBeanServer is created using {@link
       
   659      * #createNamedMBeanServer(java.lang.String, java.lang.String)
       
   660      * server =
       
   661      * MBeanServerFactory.createNamedMBeanServer("com.mycompany.myapp.server1",
       
   662      * null)} then {@code MBeanServerFactory.getMBeanServerName(server)}
       
   663      * will return {@code "com.mycompany.myapp.server1"} and
       
   664      * <code>server.getAttribute({@link
       
   665      * javax.management.MBeanServerDelegate#DELEGATE_NAME
       
   666      * MBeanServerDelegate.DELEGATE_NAME}, "MBeanServerId")</code> will return
       
   667      * something like
       
   668      * {@code "myhost_1213353064145;mbeanServerName=com.mycompany.myapp.server1"}.
       
   669      * </p>
       
   670      * <p>See the section about <a href="#MBeanServerName">MBean Server names</a>
       
   671      * above.</p>
       
   672      * @param  server A named (or unnamed) MBeanServer.
       
   673      * @return the name of the MBeanServer if found, or
       
   674      *         {@value #DEFAULT_MBEANSERVER_NAME} if no name is
       
   675      *         present in its MBeanServerId, or "*" if its
       
   676      *         MBeanServerId couldn't be obtained. Returning "*" means that
       
   677      *         only {@link MBeanPermission}s that allow all MBean Server names
       
   678      *         will apply to this MBean Server.
       
   679      * @see MBeanServerDelegate
       
   680      * @since 1.7
       
   681      */
       
   682     public static String getMBeanServerName(MBeanServer server) {
       
   683         return Util.getMBeanServerSecurityName(server);
       
   684     }
       
   685 
       
   686     /**
   374      * Return the ClassLoaderRepository used by the given MBeanServer.
   687      * Return the ClassLoaderRepository used by the given MBeanServer.
   375      * This method is equivalent to {@link MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}.
   688      * This method is equivalent to {@link
       
   689      * MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}.
   376      * @param server The MBeanServer under examination. Since JMX 1.2,
   690      * @param server The MBeanServer under examination. Since JMX 1.2,
   377      * if <code>server</code> is <code>null</code>, the result is a
   691      * if <code>server</code> is <code>null</code>, the result is a
   378      * {@link NullPointerException}.  This behavior differs from what
   692      * {@link NullPointerException}.  This behavior differs from what
   379      * was implemented in JMX 1.1 - where the possibility to use
   693      * was implemented in JMX 1.1 - where the possibility to use
   380      * <code>null</code> was deprecated.
   694      * <code>null</code> was deprecated.
   385      *
   699      *
   386      * @exception NullPointerException if <code>server</code> is null.
   700      * @exception NullPointerException if <code>server</code> is null.
   387      *
   701      *
   388      **/
   702      **/
   389     public static ClassLoaderRepository getClassLoaderRepository(
   703     public static ClassLoaderRepository getClassLoaderRepository(
   390                                             MBeanServer server) {
   704             MBeanServer server) {
   391         return server.getClassLoaderRepository();
   705         return server.getClassLoaderRepository();
   392     }
   706     }
   393 
   707 
   394     private static String mBeanServerName(MBeanServer mbs) {
   708     private static String mBeanServerId(MBeanServer mbs) {
   395         try {
   709         try {
   396             return (String) mbs.getAttribute(MBeanServerDelegate.DELEGATE_NAME,
   710             return (String) mbs.getAttribute(MBeanServerDelegate.DELEGATE_NAME,
   397                                              "MBeanServerId");
   711                     "MBeanServerId");
   398         } catch (JMException e) {
   712         } catch (JMException e) {
       
   713             JmxProperties.MISC_LOGGER.finest(
       
   714                     "Ignoring exception while getting MBeanServerId: "+e);
   399             return null;
   715             return null;
   400         }
   716         }
   401     }
   717     }
   402 
   718 
   403     private static void checkPermission(String action)
   719     private static void checkPermission(String action)
   404             throws SecurityException {
   720     throws SecurityException {
   405         SecurityManager sm = System.getSecurityManager();
   721         SecurityManager sm = System.getSecurityManager();
   406         if (sm != null) {
   722         if (sm != null) {
   407             Permission perm = new MBeanServerPermission(action);
   723             Permission perm = new MBeanServerPermission(action);
   408             sm.checkPermission(perm);
   724             sm.checkPermission(perm);
   409         }
   725         }
   423             throw new IllegalArgumentException("MBeanServer was not in list!");
   739             throw new IllegalArgumentException("MBeanServer was not in list!");
   424         }
   740         }
   425     }
   741     }
   426 
   742 
   427     private static final ArrayList<MBeanServer> mBeanServerList =
   743     private static final ArrayList<MBeanServer> mBeanServerList =
   428         new ArrayList<MBeanServer>();
   744             new ArrayList<MBeanServer>();
   429 
   745 
   430     /**
   746     /**
   431      * Load the builder class through the context class loader.
   747      * Load the builder class through the context class loader.
   432      * @param builderClassName The name of the builder class.
   748      * @param builderClassName The name of the builder class.
   433      **/
   749      **/
   434     private static Class loadBuilderClass(String builderClassName)
   750     private static Class loadBuilderClass(String builderClassName)
   435             throws ClassNotFoundException {
   751     throws ClassNotFoundException {
   436         final ClassLoader loader =
   752         final ClassLoader loader =
   437             Thread.currentThread().getContextClassLoader();
   753                 Thread.currentThread().getContextClassLoader();
   438 
   754 
   439         if (loader != null) {
   755         if (loader != null) {
   440             // Try with context class loader
   756             // Try with context class loader
   441             return loader.loadClass(builderClassName);
   757             return loader.loadClass(builderClassName);
   442         }
   758         }
   451      * If any checked exception needs to be thrown, it is embedded in
   767      * If any checked exception needs to be thrown, it is embedded in
   452      * a JMRuntimeException.
   768      * a JMRuntimeException.
   453      **/
   769      **/
   454     private static MBeanServerBuilder newBuilder(Class builderClass) {
   770     private static MBeanServerBuilder newBuilder(Class builderClass) {
   455         try {
   771         try {
   456             final Object builder = builderClass.newInstance();
   772             final Object abuilder = builderClass.newInstance();
   457             return (MBeanServerBuilder)builder;
   773             return (MBeanServerBuilder)abuilder;
   458         } catch (RuntimeException x) {
   774         } catch (RuntimeException x) {
   459             throw x;
   775             throw x;
   460         } catch (Exception x) {
   776         } catch (Exception x) {
   461             final String msg =
   777             final String msg =
   462                "Failed to instantiate a MBeanServerBuilder from " +
   778                     "Failed to instantiate a MBeanServerBuilder from " +
   463                builderClass + ": " + x;
   779                     builderClass + ": " + x;
   464             throw new JMRuntimeException(msg, x);
   780             throw new JMRuntimeException(msg, x);
   465         }
   781         }
   466     }
   782     }
   467 
   783 
   468     /**
   784     /**
   470      * javax.management.builder.initial System property - if needed.
   786      * javax.management.builder.initial System property - if needed.
   471      **/
   787      **/
   472     private static synchronized void checkMBeanServerBuilder() {
   788     private static synchronized void checkMBeanServerBuilder() {
   473         try {
   789         try {
   474             GetPropertyAction act =
   790             GetPropertyAction act =
   475                 new GetPropertyAction(JMX_INITIAL_BUILDER);
   791                     new GetPropertyAction(JMX_INITIAL_BUILDER);
   476             String builderClassName = AccessController.doPrivileged(act);
   792             String builderClassName = AccessController.doPrivileged(act);
   477 
   793 
   478             try {
   794             try {
   479                 final Class newBuilderClass;
   795                 final Class newBuilderClass;
   480                 if (builderClassName == null || builderClassName.length() == 0)
   796                 if (builderClassName == null || builderClassName.length() == 0)
   491 
   807 
   492                 // Create a new builder
   808                 // Create a new builder
   493                 builder = newBuilder(newBuilderClass);
   809                 builder = newBuilder(newBuilderClass);
   494             } catch (ClassNotFoundException x) {
   810             } catch (ClassNotFoundException x) {
   495                 final String msg =
   811                 final String msg =
   496                     "Failed to load MBeanServerBuilder class " +
   812                         "Failed to load MBeanServerBuilder class " +
   497                     builderClassName + ": " + x;
   813                         builderClassName + ": " + x;
   498                 throw new JMRuntimeException(msg, x);
   814                 throw new JMRuntimeException(msg, x);
   499             }
   815             }
   500         } catch (RuntimeException x) {
   816         } catch (RuntimeException x) {
   501             if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
   817             if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
   502                 StringBuilder strb = new StringBuilder()
   818                 StringBuilder strb = new StringBuilder()