📄 defaultmbeanserverinterceptor.java
字号:
/* * @(#)DefaultMBeanServerInterceptor.java 1.87 06/07/12 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.jmx.interceptor;// java importimport java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Set;import java.util.HashSet;import java.util.WeakHashMap;import java.lang.ref.WeakReference;import java.io.PrintWriter;import java.io.StringWriter;import java.security.AccessControlContext;import java.security.Permission;import java.security.ProtectionDomain;import java.security.AccessController;import java.security.PrivilegedAction;// JMX importimport javax.management.Attribute;import javax.management.AttributeList;import javax.management.AttributeNotFoundException;import javax.management.DynamicMBean;import javax.management.InstanceAlreadyExistsException;import javax.management.InstanceNotFoundException;import javax.management.IntrospectionException;import javax.management.InvalidAttributeValueException;import javax.management.JMException;import javax.management.JMRuntimeException;import javax.management.ListenerNotFoundException;import javax.management.MalformedObjectNameException;import javax.management.MBeanException;import javax.management.MBeanInfo;import javax.management.MBeanPermission;import javax.management.MBeanRegistration;import javax.management.MBeanRegistrationException;import javax.management.MBeanServer;import javax.management.MBeanServerDelegate;import javax.management.MBeanServerNotification;import javax.management.MBeanTrustPermission;import javax.management.NotCompliantMBeanException;import javax.management.Notification;import javax.management.NotificationBroadcaster;import javax.management.NotificationEmitter;import javax.management.NotificationFilter;import javax.management.NotificationListener;import javax.management.ObjectInstance;import javax.management.ObjectName;import javax.management.QueryEval;import javax.management.QueryExp;import javax.management.ReflectionException;import javax.management.RuntimeErrorException;import javax.management.RuntimeMBeanException;import javax.management.RuntimeOperationsException;// JMX RIimport com.sun.jmx.mbeanserver.DynamicMBean2;import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;import com.sun.jmx.mbeanserver.MBeanInstantiator;import com.sun.jmx.mbeanserver.MXBeanSupport;import com.sun.jmx.mbeanserver.Repository;import com.sun.jmx.mbeanserver.NamedObject;import com.sun.jmx.defaults.ServiceName;import com.sun.jmx.mbeanserver.Introspector;import com.sun.jmx.remote.util.EnvHelp;import com.sun.jmx.trace.Trace;/** * This is the default class for MBean manipulation on the agent side. It * contains the methods necessary for the creation, registration, and * deletion of MBeans as well as the access methods for registered MBeans. * This is the core component of the JMX infrastructure. * <P> * Every MBean which is added to the MBean server becomes manageable: its attributes and operations * become remotely accessible through the connectors/adaptors connected to that MBean server. * A Java object cannot be registered in the MBean server unless it is a JMX compliant MBean. * <P> * When an MBean is registered or unregistered in the MBean server an * {@link javax.management.MBeanServerNotification MBeanServerNotification} * Notification is emitted. To register an object as listener to MBeanServerNotifications * you should call the MBean server method {@link #addNotificationListener addNotificationListener} with <CODE>ObjectName</CODE> * the <CODE>ObjectName</CODE> of the {@link javax.management.MBeanServerDelegate MBeanServerDelegate}. * This <CODE>ObjectName</CODE> is: * <BR> * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>. * * @since 1.5 * @since.unbundled JMX RI 1.2 */public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { /** The MBeanInstantiator object used by the * DefaultMBeanServerInterceptor */ private final transient MBeanInstantiator instantiator; /** The MBean server object that is associated to the * DefaultMBeanServerInterceptor */ private transient MBeanServer server = null; /** The MBean server object taht associated to the * DefaultMBeanServerInterceptor */ private final transient MBeanServerDelegate delegate; /** The Repository object used by the DefaultMBeanServerInterceptor */ private final transient Repository repository; /** Wrappers for client listeners. */ /* See the comment before addNotificationListener below. */ private final transient WeakHashMap<ListenerWrapper, WeakReference<ListenerWrapper>> listenerWrappers = new WeakHashMap<ListenerWrapper, WeakReference<ListenerWrapper>>(); /** The default domain of the object names */ private final String domain; /** True if the repository perform queries, false otherwise */ private boolean queryByRepo; /** The sequence number identifyng the notifications sent */ // Now sequence number is handled by MBeanServerDelegate. // private int sequenceNumber=0; /** The name of this class to be used for tracing */ private final static String dbgTag = "DefaultMBeanServerInterceptor"; /** * Creates a DefaultMBeanServerInterceptor with the specified * repository instance. * <p>Do not forget to call <code>initialize(outer,delegate)</code> * before using this object. * @param outer A pointer to the MBeanServer object that must be * passed to the MBeans when invoking their * {@link javax.management.MBeanRegistration} interface. * @param delegate A pointer to the MBeanServerDelegate associated * with the new MBeanServer. The new MBeanServer must register * this MBean in its MBean repository. * @param instantiator The MBeanInstantiator that will be used to * instantiate MBeans and take care of class loading issues. * @param metadata The MetaData object that will be used by the * MBean server in order to invoke the MBean interface of * the registered MBeans. * @param repository The repository to use for this MBeanServer */ public DefaultMBeanServerInterceptor(MBeanServer outer, MBeanServerDelegate delegate, MBeanInstantiator instantiator, Repository repository) { if (outer == null) throw new IllegalArgumentException("outer MBeanServer cannot be null"); if (delegate == null) throw new IllegalArgumentException("MBeanServerDelegate cannot be null"); if (instantiator == null) throw new IllegalArgumentException("MBeanInstantiator cannot be null"); if (repository == null) throw new IllegalArgumentException("Repository cannot be null"); this.server = outer; this.delegate = delegate; this.instantiator = instantiator; this.repository = repository; this.domain = repository.getDefaultDomain(); } public ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException { return createMBean(className, name, (Object[]) null, (String[]) null); } public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { return createMBean(className, name, loaderName, (Object[]) null, (String[]) null); } public ObjectInstance createMBean(String className, ObjectName name, Object[] params, String[] signature) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException { try { return createMBean(className, name, null, true, params, signature); } catch (InstanceNotFoundException e) { /* Can only happen if loaderName doesn't exist, but we just passed null, so we shouldn't get this exception. */ throw EnvHelp.initCause( new IllegalArgumentException("Unexpected exception: " + e), e); } } public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object[] params, String[] signature) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { return createMBean(className, name, loaderName, false, params, signature); } private ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, boolean withDefaultLoaderRepository, Object[] params, String[] signature) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { ObjectName logicalName = name; Class theClass; if (className == null) { final RuntimeException wrapped = new IllegalArgumentException("The class name cannot be null"); throw new RuntimeOperationsException(wrapped, "Exception occurred during MBean creation"); } if (name != null) { if (name.isPattern()) { final RuntimeException wrapped = new IllegalArgumentException("Invalid name->" + name.toString()); final String msg = "Exception occurred during MBean creation"; throw new RuntimeOperationsException(wrapped, msg); } name = nonDefaultDomain(name); } checkMBeanPermission(className, null, null, "instantiate"); checkMBeanPermission(className, null, name, "registerMBean"); /* Load the appropriate class. */ if (withDefaultLoaderRepository) { if (isTraceOn()) { trace(dbgTag, "createMBean", "ClassName = " + className + ",ObjectName = " + name); } theClass = instantiator.findClassWithDefaultLoaderRepository(className); } else if (loaderName == null) { if (isTraceOn()) { trace(dbgTag, "createMBean", "ClassName = " + className + ",ObjectName = " + name + " Loader name = null"); } theClass = instantiator.findClass(className, server.getClass().getClassLoader()); } else { loaderName = nonDefaultDomain(loaderName); if (isTraceOn()) { trace(dbgTag, "createMBean", "ClassName = " + className + ",ObjectName = " + name + ",Loader name = "+ loaderName.toString()); } theClass = instantiator.findClass(className, loaderName); } checkMBeanTrustPermission(theClass); // Check that the MBean can be instantiated by the MBeanServer. Introspector.testCreation(theClass); // Check the JMX MBean compliance of the class Introspector.checkCompliance(theClass); Object moi= instantiator.instantiate(theClass, params, signature, server.getClass().getClassLoader()); final String infoClassName = getNewMBeanClassName(moi); return registerObject(infoClassName, moi, name); } public ObjectInstance registerMBean(Object object, ObjectName name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { // ------------------------------ // ------------------------------ Class theClass = object.getClass(); Introspector.checkCompliance(theClass); final String infoClassName = getNewMBeanClassName(object); checkMBeanPermission(infoClassName, null, name, "registerMBean"); checkMBeanTrustPermission(theClass); return registerObject(infoClassName, object, name); } private static String getNewMBeanClassName(Object mbeanToRegister) throws NotCompliantMBeanException { if (mbeanToRegister instanceof DynamicMBean) { DynamicMBean mbean = (DynamicMBean) mbeanToRegister; final String name; try { name = mbean.getMBeanInfo().getClassName(); } catch (Exception e) { // Includes case where getMBeanInfo() returns null NotCompliantMBeanException ncmbe = new NotCompliantMBeanException("Bad getMBeanInfo()"); ncmbe.initCause(e); throw ncmbe; } if (name == null) { final String msg = "MBeanInfo has null class name"; throw new NotCompliantMBeanException(msg); } return name; } else return mbeanToRegister.getClass().getName(); } private final Set<ObjectName> beingUnregistered = new HashSet<ObjectName>(); public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException { if (name == null) { final RuntimeException wrapped = new IllegalArgumentException("Object name cannot be null"); throw new RuntimeOperationsException(wrapped, "Exception occurred trying to unregister the MBean"); } name = nonDefaultDomain(name); /* The semantics of preDeregister are tricky. If it throws an exception, then the unregisterMBean fails. This allows an MBean to refuse to be unregistered. If it returns successfully, then the unregisterMBean can proceed. In this case the preDeregister may have cleaned up some state, and will not expect to be called a second time. So if two threads try to unregister the same MBean at the same time then one of them must wait for the other one to either (a) call preDeregister and get an exception or (b) call preDeregister successfully and unregister the MBean. Suppose thread T1 is unregistering an MBean and thread T2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -