📄 defaultmbeanserverinterceptor.java
字号:
/* * @(#)DefaultMBeanServerInterceptor.java 1.64 04/03/18 * * Copyright 2004 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.Set;import java.util.HashSet;import java.util.WeakHashMap;import java.lang.ref.WeakReference;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Constructor;import java.io.OptionalDataException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.PrintWriter;import java.io.StringWriter;import java.io.IOException;import java.security.AccessControlContext;import java.security.Permission;import java.security.ProtectionDomain;import java.security.AccessController;import java.security.PrivilegedAction;// JMX importimport javax.management.*;import javax.management.loading.ClassLoaderRepository;// JMX RIimport com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;import com.sun.jmx.mbeanserver.MetaData;import com.sun.jmx.mbeanserver.MetaDataImpl;import com.sun.jmx.mbeanserver.MBeanInstantiator;import com.sun.jmx.mbeanserver.Repository;import com.sun.jmx.mbeanserver.RepositorySupport;import com.sun.jmx.mbeanserver.NamedObject;import com.sun.jmx.defaults.ServiceName;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 { /** MBeanServerDelegate ObjectName shared ref */ private final static ObjectName _MBSDelegateObjectName; static { try { _MBSDelegateObjectName = new ObjectName(ServiceName.DELEGATE); } catch (MalformedObjectNameException e) { throw new UnsupportedOperationException(e.getMessage()); } } /** 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 Metadata object used by the DefaultMBeanServerInterceptor */ private final transient MetaData meta; /** 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 listenerWrappers = new WeakHashMap(); /** 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 * default domain name. * The default domain name is used as the domain part in the ObjectName * of MBeans if no domain is specified by the user. * <p>Do not forget to call <code>initialize(outer,delegate)</code> * before using this object. * @param domain The default domain name used by this MBeanServer. * @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. */ public DefaultMBeanServerInterceptor(String domain, MBeanServer outer, MBeanServerDelegate delegate, MBeanInstantiator instantiator) { this(outer, delegate, instantiator, null, new RepositorySupport((domain==null?ServiceName.DOMAIN:domain))); } /** * 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, MetaData metadata, 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 (metadata == null) metadata = new MetaDataImpl(instantiator); if (repository == null) repository = new RepositorySupport(ServiceName.DOMAIN); this.server = outer; this.delegate = delegate; this.instantiator = instantiator; this.meta = metadata; 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 new IllegalArgumentException("Unexpected exception: " + 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 occured 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); } /* Permission check */ 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); } /* Permission check */ checkMBeanTrustPermission(theClass); // Check that the MBean can be instantiated by the MBeanServer. instantiator.testCreation(theClass); // Check the JMX compliance of the class meta.testCompliance(theClass); Object moi= instantiator.instantiate(theClass, params, signature, server.getClass().getClassLoader()); final String infoClassName; try { infoClassName = meta.getMBeanClassName(moi); } catch (IntrospectionException e) { throw new NotCompliantMBeanException(e.getMessage()); } return registerCreatedObject(infoClassName, moi, name); } public ObjectInstance registerMBean(Object object, ObjectName name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { // ------------------------------ // ------------------------------ Class theClass = object.getClass(); // Check the JMX compliance of the class meta.testCompliance(theClass); /* Permission check */ final String infoClassName; try { infoClassName = meta.getMBeanClassName(object); } catch (IntrospectionException e) { throw new NotCompliantMBeanException(e.getMessage()); } checkMBeanPermission(infoClassName, null, name, "registerMBean"); checkMBeanTrustPermission(theClass); return registerObject(infoClassName, object, name); } public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException { Object object; if (name == null) { final RuntimeException wrapped = new IllegalArgumentException("Object name cannot be null"); throw new RuntimeOperationsException(wrapped, "Exception occured trying to unregister the MBean"); } name = nonDefaultDomain(name); /* Permission check */ Object instance = getMBean(name); String classname = null; try { classname = meta.getMBeanClassName(instance); } catch (IntrospectionException e) { classname = null; } catch (NotCompliantMBeanException e) { classname = null; } checkMBeanPermission(classname, null, name, "unregisterMBean"); /* We synchronize here to be sure that the preDeregister method will be invoked exactly once, even if more than one thread unregisters the MBean at the same time. */ synchronized(this) { object = repository.retrieve(name); if (object==null) { if (isTraceOn()) { trace("unregisterMBean", name+": Found no object"); } throw new InstanceNotFoundException(name.toString()); } if (object instanceof MBeanRegistration) { meta.preDeregisterInvoker(object); } // Let the repository do the work. try { repository.remove(name); } catch (InstanceNotFoundException e) { throw e; } /** * Checks if the unregistered MBean is a ClassLoader * If so, it removes the MBean from the default loader repository. */ if (object instanceof ClassLoader && object != server.getClass().getClassLoader()) { final ModifiableClassLoaderRepository clr = instantiator.getClassLoaderRepository(); if (clr != null) clr.removeClassLoader(name); } } // --------------------- // Send deletion event // --------------------- if (isTraceOn()) { trace("unregisterMBean", "Send delete notification of object " + name.getCanonicalName()); } sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION, name); if (object instanceof MBeanRegistration) { meta.postDeregisterInvoker(object); } } public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException { name = nonDefaultDomain(name); Object obj = getMBean(name); final String className; try { className = meta.getMBeanClassName(obj); } catch (IntrospectionException x) { debugX("getObjectInstance",x); throw new JMRuntimeException("Can't obtain class name for " + name + ": " + x); } catch (NotCompliantMBeanException x) { debugX("getObjectInstance",x); throw new JMRuntimeException("Can't obtain class name for " + name + ": " + x); } /* Permission check */ checkMBeanPermission(className, null, name, "getObjectInstance"); return new ObjectInstance(name, className); } public Set queryMBeans(ObjectName name, QueryExp query) { /* Permission check */ SecurityManager sm = System.getSecurityManager(); if (sm != null) { // Check if the caller has the right to invoke 'queryMBeans' //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -