Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/management/MBeanServerFactory.java
38829 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.management;2627import com.sun.jmx.defaults.JmxProperties;28import static com.sun.jmx.defaults.JmxProperties.JMX_INITIAL_BUILDER;29import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;30import com.sun.jmx.mbeanserver.GetPropertyAction;31import java.security.AccessController;32import java.security.Permission;33import java.util.ArrayList;34import java.util.logging.Level;35import javax.management.loading.ClassLoaderRepository;36import sun.reflect.misc.ReflectUtil;373839/**40* <p>Provides MBean server references. There are no instances of41* this class.</p>42*43* <p>Since JMX 1.2 this class makes it possible to replace the default44* MBeanServer implementation. This is done using the45* {@link javax.management.MBeanServerBuilder} class.46* The class of the initial MBeanServerBuilder to be47* instantiated can be specified through the48* <b>javax.management.builder.initial</b> system property.49* The specified class must be a public subclass of50* {@link javax.management.MBeanServerBuilder}, and must have a public51* empty constructor.52* <p>By default, if no value for that property is specified, an instance of53* {@link54* javax.management.MBeanServerBuilder javax.management.MBeanServerBuilder}55* is created. Otherwise, the MBeanServerFactory attempts to load the56* specified class using57* {@link java.lang.Thread#getContextClassLoader()58* Thread.currentThread().getContextClassLoader()}, or if that is null,59* {@link java.lang.Class#forName(java.lang.String) Class.forName()}. Then60* it creates an initial instance of that Class using61* {@link java.lang.Class#newInstance()}. If any checked exception62* is raised during this process (e.g.63* {@link java.lang.ClassNotFoundException},64* {@link java.lang.InstantiationException}) the MBeanServerFactory65* will propagate this exception from within a RuntimeException.</p>66*67* <p>The <b>javax.management.builder.initial</b> system property is68* consulted every time a new MBeanServer needs to be created, and the69* class pointed to by that property is loaded. If that class is different70* from that of the current MBeanServerBuilder, then a new MBeanServerBuilder71* is created. Otherwise, the MBeanServerFactory may create a new72* MBeanServerBuilder or reuse the current one.</p>73*74* <p>If the class pointed to by the property cannot be75* loaded, or does not correspond to a valid subclass of MBeanServerBuilder76* then an exception is propagated, and no MBeanServer can be created until77* the <b>javax.management.builder.initial</b> system property is reset to78* valid value.</p>79*80* <p>The MBeanServerBuilder makes it possible to wrap the MBeanServers81* returned by the default MBeanServerBuilder implementation, for the purpose82* of e.g. adding an additional security layer.</p>83*84* @since 1.585*/86public class MBeanServerFactory {8788/*89* There are no instances of this class so don't generate the90* default public constructor.91*/92private MBeanServerFactory() {9394}9596/**97* The builder that will be used to construct MBeanServers.98*99**/100private static MBeanServerBuilder builder = null;101102/**103* Provide a new {@link javax.management.MBeanServerBuilder}.104* @param builder The new MBeanServerBuilder that will be used to105* create {@link javax.management.MBeanServer}s.106* @exception IllegalArgumentException if the given builder is null.107*108* @exception SecurityException if there is a SecurityManager and109* the caller's permissions do not include or imply <code>{@link110* MBeanServerPermission}("setMBeanServerBuilder")</code>.111*112**/113// public static synchronized void114// setMBeanServerBuilder(MBeanServerBuilder builder) {115// checkPermission("setMBeanServerBuilder");116// MBeanServerFactory.builder = builder;117// }118119/**120* Get the current {@link javax.management.MBeanServerBuilder}.121*122* @return the current {@link javax.management.MBeanServerBuilder}.123*124* @exception SecurityException if there is a SecurityManager and125* the caller's permissions do not include or imply <code>{@link126* MBeanServerPermission}("getMBeanServerBuilder")</code>.127*128**/129// public static synchronized MBeanServerBuilder getMBeanServerBuilder() {130// checkPermission("getMBeanServerBuilder");131// return builder;132// }133134/**135* Remove internal MBeanServerFactory references to a created136* MBeanServer. This allows the garbage collector to remove the137* MBeanServer object.138*139* @param mbeanServer the MBeanServer object to remove.140*141* @exception java.lang.IllegalArgumentException if142* <code>mbeanServer</code> was not generated by one of the143* <code>createMBeanServer</code> methods, or if144* <code>releaseMBeanServer</code> was already called on it.145*146* @exception SecurityException if there is a SecurityManager and147* the caller's permissions do not include or imply <code>{@link148* MBeanServerPermission}("releaseMBeanServer")</code>.149*/150public static void releaseMBeanServer(MBeanServer mbeanServer) {151checkPermission("releaseMBeanServer");152153removeMBeanServer(mbeanServer);154}155156/**157* <p>Return a new object implementing the MBeanServer interface158* with a standard default domain name. The default domain name159* is used as the domain part in the ObjectName of MBeans when the160* domain is specified by the user is null.</p>161*162* <p>The standard default domain name is163* <code>DefaultDomain</code>.</p>164*165* <p>The MBeanServer reference is internally kept. This will166* allow <CODE>findMBeanServer</CODE> to return a reference to167* this MBeanServer object.</p>168*169* <p>This method is equivalent to <code>createMBeanServer(null)</code>.170*171* @return the newly created MBeanServer.172*173* @exception SecurityException if there is a SecurityManager and the174* caller's permissions do not include or imply <code>{@link175* MBeanServerPermission}("createMBeanServer")</code>.176*177* @exception JMRuntimeException if the property178* <code>javax.management.builder.initial</code> exists but the179* class it names cannot be instantiated through a public180* no-argument constructor; or if the instantiated builder returns181* null from its {@link MBeanServerBuilder#newMBeanServerDelegate182* newMBeanServerDelegate} or {@link183* MBeanServerBuilder#newMBeanServer newMBeanServer} methods.184*185* @exception ClassCastException if the property186* <code>javax.management.builder.initial</code> exists and can be187* instantiated but is not assignment compatible with {@link188* MBeanServerBuilder}.189*/190public static MBeanServer createMBeanServer() {191return createMBeanServer(null);192}193194/**195* <p>Return a new object implementing the {@link MBeanServer}196* interface with the specified default domain name. The given197* domain name is used as the domain part in the ObjectName of198* MBeans when the domain is specified by the user is null.</p>199*200* <p>The MBeanServer reference is internally kept. This will201* allow <CODE>findMBeanServer</CODE> to return a reference to202* this MBeanServer object.</p>203*204* @param domain the default domain name for the created205* MBeanServer. This is the value that will be returned by {@link206* MBeanServer#getDefaultDomain}.207*208* @return the newly created MBeanServer.209*210* @exception SecurityException if there is a SecurityManager and211* the caller's permissions do not include or imply <code>{@link212* MBeanServerPermission}("createMBeanServer")</code>.213*214* @exception JMRuntimeException if the property215* <code>javax.management.builder.initial</code> exists but the216* class it names cannot be instantiated through a public217* no-argument constructor; or if the instantiated builder returns218* null from its {@link MBeanServerBuilder#newMBeanServerDelegate219* newMBeanServerDelegate} or {@link220* MBeanServerBuilder#newMBeanServer newMBeanServer} methods.221*222* @exception ClassCastException if the property223* <code>javax.management.builder.initial</code> exists and can be224* instantiated but is not assignment compatible with {@link225* MBeanServerBuilder}.226*/227public static MBeanServer createMBeanServer(String domain) {228checkPermission("createMBeanServer");229230final MBeanServer mBeanServer = newMBeanServer(domain);231addMBeanServer(mBeanServer);232return mBeanServer;233}234235/**236* <p>Return a new object implementing the MBeanServer interface237* with a standard default domain name, without keeping an238* internal reference to this new object. The default domain name239* is used as the domain part in the ObjectName of MBeans when the240* domain is specified by the user is null.</p>241*242* <p>The standard default domain name is243* <code>DefaultDomain</code>.</p>244*245* <p>No reference is kept. <CODE>findMBeanServer</CODE> will not246* be able to return a reference to this MBeanServer object, but247* the garbage collector will be able to remove the MBeanServer248* object when it is no longer referenced.</p>249*250* <p>This method is equivalent to <code>newMBeanServer(null)</code>.</p>251*252* @return the newly created MBeanServer.253*254* @exception SecurityException if there is a SecurityManager and the255* caller's permissions do not include or imply <code>{@link256* MBeanServerPermission}("newMBeanServer")</code>.257*258* @exception JMRuntimeException if the property259* <code>javax.management.builder.initial</code> exists but the260* class it names cannot be instantiated through a public261* no-argument constructor; or if the instantiated builder returns262* null from its {@link MBeanServerBuilder#newMBeanServerDelegate263* newMBeanServerDelegate} or {@link264* MBeanServerBuilder#newMBeanServer newMBeanServer} methods.265*266* @exception ClassCastException if the property267* <code>javax.management.builder.initial</code> exists and can be268* instantiated but is not assignment compatible with {@link269* MBeanServerBuilder}.270*/271public static MBeanServer newMBeanServer() {272return newMBeanServer(null);273}274275/**276* <p>Return a new object implementing the MBeanServer interface277* with the specified default domain name, without keeping an278* internal reference to this new object. The given domain name279* is used as the domain part in the ObjectName of MBeans when the280* domain is specified by the user is null.</p>281*282* <p>No reference is kept. <CODE>findMBeanServer</CODE> will not283* be able to return a reference to this MBeanServer object, but284* the garbage collector will be able to remove the MBeanServer285* object when it is no longer referenced.</p>286*287* @param domain the default domain name for the created288* MBeanServer. This is the value that will be returned by {@link289* MBeanServer#getDefaultDomain}.290*291* @return the newly created MBeanServer.292*293* @exception SecurityException if there is a SecurityManager and the294* caller's permissions do not include or imply <code>{@link295* MBeanServerPermission}("newMBeanServer")</code>.296*297* @exception JMRuntimeException if the property298* <code>javax.management.builder.initial</code> exists but the299* class it names cannot be instantiated through a public300* no-argument constructor; or if the instantiated builder returns301* null from its {@link MBeanServerBuilder#newMBeanServerDelegate302* newMBeanServerDelegate} or {@link303* MBeanServerBuilder#newMBeanServer newMBeanServer} methods.304*305* @exception ClassCastException if the property306* <code>javax.management.builder.initial</code> exists and can be307* instantiated but is not assignment compatible with {@link308* MBeanServerBuilder}.309*/310public static MBeanServer newMBeanServer(String domain) {311checkPermission("newMBeanServer");312313// Get the builder. Creates a new one if necessary.314//315final MBeanServerBuilder mbsBuilder = getNewMBeanServerBuilder();316// Returned value cannot be null. NullPointerException if violated.317318synchronized(mbsBuilder) {319final MBeanServerDelegate delegate =320mbsBuilder.newMBeanServerDelegate();321if (delegate == null) {322final String msg =323"MBeanServerBuilder.newMBeanServerDelegate() " +324"returned null";325throw new JMRuntimeException(msg);326}327final MBeanServer mbeanServer =328mbsBuilder.newMBeanServer(domain,null,delegate);329if (mbeanServer == null) {330final String msg =331"MBeanServerBuilder.newMBeanServer() returned null";332throw new JMRuntimeException(msg);333}334return mbeanServer;335}336}337338/**339* <p>Return a list of registered MBeanServer objects. A340* registered MBeanServer object is one that was created by one of341* the <code>createMBeanServer</code> methods and not subsequently342* released with <code>releaseMBeanServer</code>.</p>343*344* @param agentId The agent identifier of the MBeanServer to345* retrieve. If this parameter is null, all registered346* MBeanServers in this JVM are returned. Otherwise, only347* MBeanServers whose id is equal to <code>agentId</code> are348* returned. The id of an MBeanServer is the349* <code>MBeanServerId</code> attribute of its delegate MBean.350*351* @return A list of MBeanServer objects.352*353* @exception SecurityException if there is a SecurityManager and the354* caller's permissions do not include or imply <code>{@link355* MBeanServerPermission}("findMBeanServer")</code>.356*/357public synchronized static358ArrayList<MBeanServer> findMBeanServer(String agentId) {359360checkPermission("findMBeanServer");361362if (agentId == null)363return new ArrayList<MBeanServer>(mBeanServerList);364365ArrayList<MBeanServer> result = new ArrayList<MBeanServer>();366for (MBeanServer mbs : mBeanServerList) {367String name = mBeanServerId(mbs);368if (agentId.equals(name))369result.add(mbs);370}371return result;372}373374/**375* Return the ClassLoaderRepository used by the given MBeanServer.376* This method is equivalent to {@link377* MBeanServer#getClassLoaderRepository() server.getClassLoaderRepository()}.378* @param server The MBeanServer under examination. Since JMX 1.2,379* if <code>server</code> is <code>null</code>, the result is a380* {@link NullPointerException}. This behavior differs from what381* was implemented in JMX 1.1 - where the possibility to use382* <code>null</code> was deprecated.383* @return The Class Loader Repository used by the given MBeanServer.384* @exception SecurityException if there is a SecurityManager and385* the caller's permissions do not include or imply <code>{@link386* MBeanPermission}("getClassLoaderRepository")</code>.387*388* @exception NullPointerException if <code>server</code> is null.389*390**/391public static ClassLoaderRepository getClassLoaderRepository(392MBeanServer server) {393return server.getClassLoaderRepository();394}395396private static String mBeanServerId(MBeanServer mbs) {397try {398return (String) mbs.getAttribute(MBeanServerDelegate.DELEGATE_NAME,399"MBeanServerId");400} catch (JMException e) {401JmxProperties.MISC_LOGGER.finest(402"Ignoring exception while getting MBeanServerId: "+e);403return null;404}405}406407private static void checkPermission(String action)408throws SecurityException {409SecurityManager sm = System.getSecurityManager();410if (sm != null) {411Permission perm = new MBeanServerPermission(action);412sm.checkPermission(perm);413}414}415416private static synchronized void addMBeanServer(MBeanServer mbs) {417mBeanServerList.add(mbs);418}419420private static synchronized void removeMBeanServer(MBeanServer mbs) {421boolean removed = mBeanServerList.remove(mbs);422if (!removed) {423MBEANSERVER_LOGGER.logp(Level.FINER,424MBeanServerFactory.class.getName(),425"removeMBeanServer(MBeanServer)",426"MBeanServer was not in list!");427throw new IllegalArgumentException("MBeanServer was not in list!");428}429}430431private static final ArrayList<MBeanServer> mBeanServerList =432new ArrayList<MBeanServer>();433434/**435* Load the builder class through the context class loader.436* @param builderClassName The name of the builder class.437**/438private static Class<?> loadBuilderClass(String builderClassName)439throws ClassNotFoundException {440final ClassLoader loader =441Thread.currentThread().getContextClassLoader();442443if (loader != null) {444// Try with context class loader445return loader.loadClass(builderClassName);446}447448// No context class loader? Try with Class.forName()449return ReflectUtil.forName(builderClassName);450}451452/**453* Creates the initial builder according to the454* javax.management.builder.initial System property - if specified.455* If any checked exception needs to be thrown, it is embedded in456* a JMRuntimeException.457**/458private static MBeanServerBuilder newBuilder(Class<?> builderClass) {459try {460final Object abuilder = builderClass.newInstance();461return (MBeanServerBuilder)abuilder;462} catch (RuntimeException x) {463throw x;464} catch (Exception x) {465final String msg =466"Failed to instantiate a MBeanServerBuilder from " +467builderClass + ": " + x;468throw new JMRuntimeException(msg, x);469}470}471472/**473* Instantiate a new builder according to the474* javax.management.builder.initial System property - if needed.475**/476private static synchronized void checkMBeanServerBuilder() {477try {478GetPropertyAction act =479new GetPropertyAction(JMX_INITIAL_BUILDER);480String builderClassName = AccessController.doPrivileged(act);481482try {483final Class<?> newBuilderClass;484if (builderClassName == null || builderClassName.length() == 0)485newBuilderClass = MBeanServerBuilder.class;486else487newBuilderClass = loadBuilderClass(builderClassName);488489// Check whether a new builder needs to be created490if (builder != null) {491final Class<?> builderClass = builder.getClass();492if (newBuilderClass == builderClass)493return; // no need to create a new builder...494}495496// Create a new builder497builder = newBuilder(newBuilderClass);498} catch (ClassNotFoundException x) {499final String msg =500"Failed to load MBeanServerBuilder class " +501builderClassName + ": " + x;502throw new JMRuntimeException(msg, x);503}504} catch (RuntimeException x) {505if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {506StringBuilder strb = new StringBuilder()507.append("Failed to instantiate MBeanServerBuilder: ").append(x)508.append("\n\t\tCheck the value of the ")509.append(JMX_INITIAL_BUILDER).append(" property.");510MBEANSERVER_LOGGER.logp(Level.FINEST,511MBeanServerFactory.class.getName(),512"checkMBeanServerBuilder",513strb.toString());514}515throw x;516}517}518519/**520* Get the current {@link javax.management.MBeanServerBuilder},521* as specified by the current value of the522* javax.management.builder.initial property.523*524* This method consults the property and instantiates a new builder525* if needed.526*527* @return the new current {@link javax.management.MBeanServerBuilder}.528*529* @exception SecurityException if there is a SecurityManager and530* the caller's permissions do not make it possible to instantiate531* a new builder.532* @exception JMRuntimeException if the builder instantiation533* fails with a checked exception -534* {@link java.lang.ClassNotFoundException} etc...535*536**/537private static synchronized MBeanServerBuilder getNewMBeanServerBuilder() {538checkMBeanServerBuilder();539return builder;540}541542}543544545