Logo Search packages:      
Sourcecode: jbossas4 version File versions  Download package

MBeanServerImpl.java

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.mx.server;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.security.ProtectionDomain;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
import javax.management.JMRuntimeException;
import javax.management.MBeanPermission;
import javax.management.MalformedObjectNameException;
import javax.management.MBeanTrustPermission;
import javax.management.loading.ClassLoaderRepository;
import javax.management.modelmbean.DescriptorSupport;
import javax.management.modelmbean.ModelMBean;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanConstructorInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;

import org.jboss.logging.Logger;
import org.jboss.mx.loading.LoaderRepository;
import org.jboss.mx.modelmbean.ModelMBeanConstants;
import org.jboss.mx.modelmbean.RequiredModelMBeanInstantiator;
import org.jboss.mx.notification.MBeanServerListenerRegistry;
import org.jboss.mx.server.registry.MBeanEntry;
import org.jboss.mx.server.registry.MBeanRegistry;
import org.jboss.mx.service.ServiceConstants;
import org.jboss.mx.util.JMXExceptionDecoder;
import org.jboss.mx.util.PropertyAccess;
import org.jboss.util.NestedRuntimeException;

/**
 * MBean server implementation. 
 *
 * The MBean server behaviour can be configured by setting the following
 * system properties: <ul>
 *    <li><tt>jbossmx.loader.repository.class</tt>
 ({@link ServerConstants#LOADER_REPOSITORY_CLASS_PROPERTY LOADER_REPOSITORY_CLASS_PROPERTY})</li>
 *    <li><tt>jbossmx.mbean.registry.class</tt>
 ({@link ServerConstants#MBEAN_REGISTRY_CLASS_PROPERTY MBEAN_REGISTRY_CLASS_PROPERTY})</li>
 *    <li><tt>jbossmx.required.modelmbean.class</tt>
 ({@link ServerConstants#REQUIRED_MODELMBEAN_CLASS_PROPERTY REQUIRED_MODELMBEAN_CLASS_PROPERTY})</li>
 * </ul>
 *
 * The loader repository is used for managing class loaders in the MBean server.
 * The default repository uses the <tt>UnifiedLoaderRepository</tt> implementation
 * ({@link ServerConstants#DEFAULT_LOADER_REPOSITORY_CLASS DEFAULT_LOADER_REPOSITORY_CLASS}).<p>
 *
 * The default registry is
 * ({@link ServerConstants#DEFAULT_MBEAN_REGISTRY_CLASS DEFAULT_MBEAN_REGISTRY_CLASS}).<p>
 *
 * The <tt>RequiredModelMBean</tt> uses <tt>XMBean</tt> implementation by default
 * ({@link ServerConstants#DEFAULT_REQUIRED_MODELMBEAN_CLASS DEFAULT_REQUIRED_MODELMBEAN_CLASS}).
 *
 * @see javax.management.MBeanServer
 * @see javax.management.modelmbean.RequiredModelMBean
 * @see org.jboss.mx.server.ServerConstants
 * @see org.jboss.mx.loading.LoaderRepository
 * @see org.jboss.mx.loading.UnifiedLoaderRepository3
 * @see org.jboss.mx.modelmbean.XMBean
 *
 * @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
 * @author  <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
 * @author  <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
 * @author  <a href="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
 * @author Scott.Stark@jboss.org
 * @version $Revision: 57200 $
 */
00132 public class MBeanServerImpl
   implements MBeanServer, ServerConstants, ServiceConstants, ModelMBeanConstants
{
   // Constants ------------------------------------------------------

   /**
    * No parameters array
    */
00140    private static final Object[] NOPARAMS = new Object[0];

   /**
    * No signature array
    */
00145    private static final String[] NOSIG = new String[0];

   // Attributes ----------------------------------------------------

   /**
    * The wrapping MBeanServer
    */
00152    protected MBeanServer outer = null;

   /**
    * Registry used by this server to map MBean object names to resource references.
    */
00157    protected MBeanRegistry registry = null;

   /**
    * The notification registrations
    */
00162    private MBeanServerListenerRegistry listeners = new MBeanServerListenerRegistry();

   /**
    * This server's class loader repository
    */
00167    private ClassLoaderRepository classLoaderRepository;

   // Static --------------------------------------------------------

   /**
    * The logger
    */
00174    private static Logger log = Logger.getLogger(MBeanServerImpl.class);

   
   // Constructors --------------------------------------------------

   /**
    * Creates an MBean server implementation with a given default domain name and
    * registers the mandatory server delegate MBean to the server
    * ({@link ServerConstants#MBEAN_SERVER_DELEGATE MBEAN_SERVER_DELEGATE}).
    *
    * @param defaultDomain default domain name
    * @param outer the wrapping MBeanServer, passed to MBeans
    *        at registration.
    * @param delegate the delegate to use
    *        for Notifications.
    */
00190    public MBeanServerImpl(String defaultDomain, MBeanServer outer, MBeanServerDelegate delegate)
   {
      // Determine the MBeanServer to pass to MBeans
      if (outer == null)
         this.outer = this;
      else
         this.outer = outer;

      // the very first thing to do is to create a class loader repository
      this.classLoaderRepository = getClassLoaderRepository();

      // the second first thing to do is to create a registry instance
      this.registry = createRegistry(defaultDomain);
      
      // The first MBean to be registered should be the server delegate
      // to guarantee correct functionality (other MBeans may be dependent
      // on the existence of the delegate).
      try
      {
         // the magic token that allows us to register to the 
         // protected JMImplementation domain
         HashMap valueMap = new HashMap();
         valueMap.put(JMI_DOMAIN, JMI_DOMAIN);

         // register the delegate
         registry.registerMBean(delegate,
                 new ObjectName(MBEAN_SERVER_DELEGATE),
                 valueMap);
         
         // We expose the registry as an MBean for other components 
         ModelMBean rmm = RequiredModelMBeanInstantiator.instantiate();
         rmm.setModelMBeanInfo(getRegistryManagementInterface());
         rmm.setManagedResource(registry, "ObjectReference");

         // register the registry MBean
         registry.registerMBean(rmm, new ObjectName(MBEAN_REGISTRY), valueMap);
         
         // register the loader repository
         //String loaderClassMBeanName = classLoaderRepository.getClass().getName() + "MBean";
         //ClassLoader cl = classLoaderRepository.getClass().getClassLoader();
         //Class mbean = cl.loadClass(loaderClassMBeanName);
         
         //there must be a class with the MBean extension.
         ObjectName loaderName = new ObjectName(DEFAULT_LOADER_NAME);
         registry.registerMBean(classLoaderRepository, loaderName, valueMap);

      }
      catch (Exception e)
      {
         throw new RuntimeException("Cannot create MBeanServer", e);
      }
   }

   // MBeanServer implementation ------------------------------------

00245    public Object instantiate(String className)
           throws ReflectionException, MBeanException
   {
      return instantiate(className, (ClassLoader) null, NOPARAMS, NOSIG);
   }

00251    public Object instantiate(String className, Object[] params, String[] signature)
           throws ReflectionException, MBeanException
   {
      return instantiate(className, (ClassLoader) null, params, signature);
   }

00257    public Object instantiate(String className, ObjectName loaderName)
           throws ReflectionException, MBeanException, InstanceNotFoundException
   {
      return instantiate(className, loaderName, NOPARAMS, NOSIG);
   }

00263    public Object instantiate(String className, ObjectName loaderName, Object[] params, String[] signature)
           throws ReflectionException, MBeanException, InstanceNotFoundException
   {
      ClassLoader cl = null;

      // if instantiate() is called with null loader name, we use the cl that
      // loaded the MBean server (see javadoc)

      try
      {
         if (loaderName != null)
            cl = (ClassLoader) registry.get(loaderName).getResourceInstance();
      }
      catch (ClassCastException e)
      {
         throw new ReflectionException(e, loaderName + " is not a class loader.");
      }

      if (cl == null)
         cl = this.getClass().getClassLoader();
      if (cl == null)
         cl = ClassLoader.getSystemClassLoader();

      return instantiate(className, cl, params, signature);
   }

00289    public ObjectInstance createMBean(String className, ObjectName name)
           throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException
   {
      try
      {
         Object mbean = instantiate(className);
         return registerMBean(mbean, name, (ClassLoader) null);
      }
      catch (SecurityException e)
      {
         throw e;
      }
      catch (ReflectionException refex)
      {
         // Note, the CTS wants a NotCompliantMBeanException for this case
         if (refex.getCause() instanceof InstantiationException)
            throw new NotCompliantMBeanException("Cannot instanciate MBean: " + className);
         else
            throw refex;
      }
   }

00311    public ObjectInstance createMBean(String className, ObjectName name, Object[] params, String[] signature)
           throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException
   {
      try
      {
         Object mbean = instantiate(className, params, signature);
         return registerMBean(mbean, name, (ClassLoader) null);
      }
      catch (ReflectionException refex)
      {
         return handleExceptionOnCreate(refex, className);
      }
   }

00325    public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName)
           throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException
   {
      try
      {
         Object mbean = instantiate(className, loaderName);
         return registerMBean(mbean, name, loaderName);
      }
      catch (ReflectionException refex)
      {
         return handleExceptionOnCreate(refex, className);
      }
   }

00339    public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object[] params, String[] signature)
           throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException
   {
      try
      {
         Object mbean = instantiate(className, loaderName, params, signature);
         return registerMBean(mbean, name, loaderName);
      }
      catch (ReflectionException refex)
      {
         return handleExceptionOnCreate(refex, className);
      }
   }

   /**
    * The CTS wants a NotCompliantMBeanException in case the MBean cannot be created.
    * We need this, because instanciate cannot throw NotCompliantMBeanException.
    */
00357    private ObjectInstance handleExceptionOnCreate(ReflectionException refex, String className)
           throws NotCompliantMBeanException, ReflectionException
   {
      if (refex.getCause() instanceof InstantiationException)
         throw new NotCompliantMBeanException("Cannot instanciate MBean: " + className);

      throw refex;
   }

   /**
    * Registers a pre-existing object as an MBean with the MBean server. If the object name given is null,
    * the MBean must provide its own name by implementing the MBeanRegistration interface and returning the name
    * from the preRegister method.
    */
00371    public ObjectInstance registerMBean(Object object, ObjectName name)
           throws InstanceAlreadyExistsException,
           MBeanRegistrationException,
           NotCompliantMBeanException
   {
      return registerMBean(object, name, (ClassLoader) null);
   }

00379    public void unregisterMBean(ObjectName name)
           throws InstanceNotFoundException, MBeanRegistrationException
   {
      // Get the mbean to remove
      MBeanEntry entry = registry.get(name);
      Object mbean = entry.getResourceInstance();
      name = entry.getObjectName();

      checkMBeanPermission(entry.getResourceClassName(), null, name, "unregisterMBean");

      try
      {
         final Object[] args = {name};
         final String[] sig = {ObjectName.class.getName()};
         try
         {
            AccessController.doPrivileged(
               new PrivilegedExceptionAction()
               {
                  public Object run() throws Exception
                  {
                     return invoke(new ObjectName(MBEAN_REGISTRY),
                        "unregisterMBean", args, sig);
                  }
               }
            );
         }
         catch(PrivilegedActionException e)
         {
            throw e.getException();
         }
      }
      catch (Throwable t)
      {
         Throwable result = JMXExceptionDecoder.decodeToJMXException(t);
         if (result instanceof InstanceNotFoundException)
            throw (InstanceNotFoundException) result;
         if (result instanceof MBeanRegistrationException)
            throw (MBeanRegistrationException) result;
         if ( result instanceof JMRuntimeException )
            throw (JMRuntimeException) result;
         if (result instanceof RuntimeException)
            throw new RuntimeMBeanException((RuntimeException) result);
         if (result instanceof Error)
            throw new RuntimeErrorException((Error) result);

         // for some other reason, unregistration failed
         throw new MBeanRegistrationException(new InvocationTargetException(t), "Cannot unregister MBean");
      }
      
      // Unregistration worked, remove any proxies for a broadcaster
      if (mbean instanceof NotificationBroadcaster)
         listeners.remove(name);
   }

00434    public ObjectInstance getObjectInstance(ObjectName name)
           throws InstanceNotFoundException
   {
      ObjectInstance oi = registry.getObjectInstance(name);
      checkMBeanPermission(oi.getClassName(), null, name,
         "getObjectInstance");

      return oi;
   }

00444    public Set queryMBeans(ObjectName name, QueryExp query)
   {
      // At least one mbean must be queriable
      checkMBeanPermission(null, null, null, "queryMBeans");

      // Set up the query
      Set result = new HashSet();
      if (query != null)
         query.setMBeanServer(outer);

      SecurityManager sm = System.getSecurityManager();
      // Get the possible MBeans
      List entries = registry.findEntries(name);
      Iterator iterator = entries.iterator();
      while (iterator.hasNext())
      {
         // Check each MBean against the query
         MBeanEntry entry = (MBeanEntry) iterator.next();
         ObjectName objectName = entry.getObjectName();
         // The permission check must be done before the query is applied
         if( sm != null )
         {
            try
            {
               checkMBeanPermission(entry.getResourceClassName(), null,
                  objectName, "queryMBeans");
            }
            catch(SecurityException e)
            {
               if( log.isTraceEnabled() )
                  log.trace("Excluded mbean due to security: "+objectName);
               continue;
            }            
         }
         // Check the mbean against the query
         if (queryMBean(objectName, query) == true)
         {
            try
            {
               ObjectInstance instance = registry.getObjectInstance(objectName);
               result.add(instance);
            }
            catch (InstanceNotFoundException ignored)
            {
            }
         }
      }

      return result;
   }

00495    public Set queryNames(ObjectName name, QueryExp query)
   {
      // At least one mbean must be queriable
      checkMBeanPermission(null, null, null, "queryNames");

      // Set up the query
      Set result = new HashSet();
      if (query != null)
         query.setMBeanServer(outer);

      SecurityManager sm = System.getSecurityManager();
      // Get the possible MBeans
      List entries = registry.findEntries(name);
      Iterator iterator = entries.iterator();
      while (iterator.hasNext())
      {
         // Check each MBean against the query
         MBeanEntry entry = (MBeanEntry) iterator.next();
         ObjectName objectName = entry.getObjectName();
         // The permission check must be done before the query is applied
         if( sm != null )
         {
            try
            {
               checkMBeanPermission(entry.getResourceClassName(), null,
                  objectName, "queryNames");
            }
            catch(SecurityException e)
            {
               if( log.isTraceEnabled() )
                  log.trace("Excluded mbean due to security: "+objectName);
               continue;
            }            
         }
         // Check the mbean against the query
         if (queryMBean(objectName, query) == true)
            result.add(objectName);
      }

      return result;
   }

00537    public boolean isRegistered(ObjectName name)
   {
      return registry.contains(name);
   }

00542    public java.lang.Integer getMBeanCount()
   {
      return new Integer(registry.getSize());
   }

00547    public Object getAttribute(ObjectName name, String attribute)
           throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException
   {
      MBeanEntry entry = registry.get(name);
      checkMBeanPermission(entry.getResourceClassName(), attribute, name,
         "getAttribute");

      MBeanInvoker mbean = entry.getInvoker();

      return mbean.getAttribute(attribute);
   }

00559    public AttributeList getAttributes(ObjectName name, String[] attributes)
           throws InstanceNotFoundException, ReflectionException
   {
      MBeanEntry entry = registry.get(name);
      String className = entry.getResourceClassName();
      /* Access to an attribute is required and this check will fail only
      if access to no attributes are allowed and will result in a security
      exception rather than an empty list.
      */
      checkMBeanPermission(className, null, name, "getAttribute");
      
      MBeanInvoker mbean = entry.getInvoker();
      AttributeList list = mbean.getAttributes(attributes);
      SecurityManager sm = System.getSecurityManager();
      if( sm != null )
      {
         // Remove any attributes that are not allowed
         Iterator iter = list.iterator();
         while( iter.hasNext() )
         {
            Attribute attr = (Attribute) iter.next();
            String aname = attr.getName();
            try
            {
               checkMBeanPermission(className, aname, name, "getAttribute");
            }
            catch(SecurityException e)
            {
               if( log.isTraceEnabled() )
                  log.trace("Excluded attribute due to security: "+aname);
               iter.remove();
            }
         }
      }
      return list;
   }

00596    public void setAttribute(ObjectName name, Attribute attribute)
           throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException
   {
      MBeanEntry entry = registry.get(name);
      String attributeName = null;
      if (attribute != null)
         attributeName = attribute.getName();
      checkMBeanPermission(entry.getResourceClassName(), attributeName,
         name, "setAttribute");

      MBeanInvoker mbean = entry.getInvoker();

      mbean.setAttribute(attribute);
   }

00611    public AttributeList setAttributes(ObjectName name, AttributeList attributes)
           throws InstanceNotFoundException, ReflectionException
   {
      MBeanEntry entry = registry.get(name);

      String className = entry.getResourceClassName();
      /* Access to an attribute is required and this check will fail only
      if access to no attributes are allowed and will result in a security
      exception rather than an empty list.
      */
      checkMBeanPermission(className, null, name, "setAttribute");

      MBeanInvoker mbean = entry.getInvoker();
      AttributeList list = mbean.setAttributes(attributes);
      SecurityManager sm = System.getSecurityManager();
      if( sm != null )
      {
         // Remove any attributes that are not allowed
         Iterator iter = list.iterator();
         while( iter.hasNext() )
         {
            Attribute attr = (Attribute) iter.next();
            String aname = attr.getName();
            try
            {
               checkMBeanPermission(className, aname, name, "setAttribute");
            }
            catch(SecurityException e)
            {
               if( log.isTraceEnabled() )
                  log.trace("Excluded attribute due to security: "+aname);
               iter.remove();
            }
         }
      }
      return list;
   }

00649    public Object invoke(ObjectName name, String operationName, Object[] params,
      String[] signature)
      throws InstanceNotFoundException, MBeanException, ReflectionException
   {
      MBeanEntry entry = registry.get(name);
      checkMBeanPermission(entry.getResourceClassName(), operationName, name,
         "invoke");

      MBeanInvoker mbean = entry.getInvoker();

      return mbean.invoke(operationName, params, signature);
   }

00662    public MBeanInfo getMBeanInfo(ObjectName name)
      throws InstanceNotFoundException, IntrospectionException,
      ReflectionException
   {
      MBeanEntry entry = registry.get(name);
      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "getMBeanInfo");
      try
      {
         MBeanInvoker invoker = entry.getInvoker();
         return invoker.getMBeanInfo();
      }
      catch (Exception e)
      {
         JMException result = ExceptionHandler.handleException(e);
         if (result instanceof InstanceNotFoundException)
            throw (InstanceNotFoundException) result;
         if (result instanceof IntrospectionException)
            throw (IntrospectionException) result;
         if (result instanceof ReflectionException)
            throw (ReflectionException) result;
         throw new RuntimeException("Cannot obtain MBeanInfo " + name, result);
      }
   }

00687    public String getDefaultDomain()
   {
      return registry.getDefaultDomain();
   }

00692    public String[] getDomains()
   {
      checkMBeanPermission(null, null, null, "getDomains");
      String[] domains = registry.getDomains();
      SecurityManager sm = System.getSecurityManager();
      if( sm != null )
      {
         ArrayList tmp = new ArrayList();
         // Remove any domains that are not allowed
         int length = domains != null ? domains.length : 0;
         for(int n = 0; n < length; n ++)
         {
            String domain = domains[n];
            try
            {
               ObjectName name = new ObjectName(domain, "x", "x");
               checkMBeanPermission(null, null, name, "getDomains");
               tmp.add(domain);
            }
            catch(MalformedObjectNameException e)
            {
               // Should not be possible
            }
            catch(SecurityException e)
            {
               if( log.isTraceEnabled() )
                  log.trace("Excluded domain due to security: "+domain);
            }
         }
         domains = new String[tmp.size()];
         tmp.toArray(domains);
      }
      return domains;
   }

   /**
    * Adds a listener to a registered MBean.
    *
    * A notification emitted by the MBean will be forwarded by the MBeanServer to the listener.
    * If the source of the notification is a reference to the MBean object, the MBean server will replace
    * it by the MBean's ObjectName. Otherwise the source is unchanged.
    */
00734    public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback)
           throws InstanceNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean named exists but does not implement the NotificationBroadcaster interface."));

      if (listener == null)
         throw new RuntimeOperationsException(new IllegalArgumentException("Cannot add null listener"));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "addNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();
      NotificationBroadcaster broadcaster = entry.getInvoker();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.add(entry.getObjectName(), broadcaster, listener, filter, handback);
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Adds a listener to a registered MBean.
    *
    * A notification emitted by the MBean will be forwarded by the MBeanServer to the listener.
    * If the source of the notification is a reference to the MBean object, the MBean server will replace
    * it by the MBean's ObjectName. Otherwise the source is unchanged.
    *
    * The listener object that receives notifications is the one that is registered with the given name at the time this
    * method is called. Even if it is subsequently unregistered, it will continue to receive notifications.
    */
00776    public void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback)
           throws InstanceNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));

      MBeanEntry listenerEntry = registry.get(listener);
      if (NotificationListener.class.isInstance(listenerEntry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + listener + " exists but does not implement the NotificationListener interface."));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "addNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();
      NotificationBroadcaster broadcaster = entry.getInvoker();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.add(entry.getObjectName(), broadcaster,
                 (NotificationListener) registry.get(listener).getResourceInstance(), filter, handback);
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Removes a listener from a registered MBean.
    *
    * If the listener is registered more than once, perhaps with different filters or callbacks,
    * this method will remove all those registrations.
    */
00816    public void removeNotificationListener(ObjectName name, NotificationListener listener)
           throws InstanceNotFoundException, ListenerNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "removeNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.remove(entry.getObjectName(), listener);
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Removes a listener from a registered MBean.
    *
    * If the listener is registered more than once, perhaps with different filters or callbacks,
    * this method will remove all those registrations.
    */
00850    public void removeNotificationListener(ObjectName name, ObjectName listener)
           throws InstanceNotFoundException, ListenerNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));

      MBeanEntry listenerEntry = registry.get(listener);
      if (NotificationListener.class.isInstance(listenerEntry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + listener + " exists but does not implement the NotificationListener interface."));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "removeNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.remove(entry.getObjectName(), (NotificationListener) registry.get(listener).getResourceInstance());
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Removes a listener from a registered MBean.
    *
    * The MBean must have a listener that exactly matches the given listener, filter, and handback parameters.
    * If there is more than one such listener, only one is removed.
    *
    * The filter and handback parameters may be null if and only if they are null in a listener to be removed.
    */
00890    public void removeNotificationListener(ObjectName name,
      NotificationListener listener, NotificationFilter filter, Object handback)
      throws InstanceNotFoundException, ListenerNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "removeNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.remove(entry.getObjectName(), listener, filter, handback);
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Removes a listener from a registered MBean.
    *
    * The MBean must have a listener that exactly matches the given listener, filter, and handback parameters.
    * If there is more than one such listener, only one is removed.
    *
    * The filter and handback parameters may be null if and only if they are null in a listener to be removed.
    */
00927    public void removeNotificationListener(ObjectName name, ObjectName listener,
      NotificationFilter filter, Object handback)
      throws InstanceNotFoundException, ListenerNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      if (NotificationBroadcaster.class.isInstance(entry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));

      MBeanEntry listenerEntry = registry.get(listener);
      if (NotificationListener.class.isInstance(listenerEntry.getResourceInstance()) == false)
         throw new RuntimeOperationsException(new IllegalArgumentException("The MBean " + listener + " exists but does not implement the NotificationListener interface."));

      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "removeNotificationListener");

      ClassLoader newTCL = entry.getClassLoader();

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();
      final boolean setCl = newTCL != oldTCL && newTCL != null;
      try
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(newTCL);

         listeners.remove(entry.getObjectName(), (NotificationListener) registry.get(listener).getResourceInstance(),
                 filter, handback);
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

00961    public boolean isInstanceOf(ObjectName name, String className)
           throws InstanceNotFoundException
   {
      // Get the MBean's class name
      MBeanEntry entry = registry.get(name);
      String mbeanClassName = entry.getResourceClassName();
      checkMBeanPermission(mbeanClassName, null, name, "isInstanceOf");

      // The names are the same
      if (className.equals(mbeanClassName))
         return true;

      // Try to load both classes
      Class mbeanClass = null;
      Class testClass = null;
      ClassLoader cl = getClassLoaderFor(name);
      try
      {
         mbeanClass = cl.loadClass(mbeanClassName);
         testClass = cl.loadClass(className);
      }
      catch (ClassNotFoundException e)
      {
         return false;
      }

      // Check whether it is assignable
      if (testClass.isAssignableFrom(mbeanClass))
         return true;
      else
         return false;
   }

   /**
    * @deprecated
    */
00997    public ObjectInputStream deserialize(ObjectName name, byte[] data) throws InstanceNotFoundException, OperationsException
   {
      try
      {
         ClassLoader cl = this.getClassLoaderFor(name);
         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(data), cl);
      }
      catch (IOException e)
      {
         throw new OperationsException("I/O exception deserializing: " + e.getMessage());
      }
   }

   /**
    * @deprecated
    */
01013    public ObjectInputStream deserialize(String className, byte[] data)
      throws OperationsException, ReflectionException
   {
      try
      {
         Class c = this.getClassLoaderRepository().loadClass(className);
         ClassLoader cl = c.getClassLoader();
         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(data), cl);
      }
      catch (IOException e)
      {
         throw new OperationsException("I/O exception deserializing: " + e.getMessage());
      }
      catch (ClassNotFoundException e)
      {
         throw new ReflectionException(e, "Class not found from default repository: " + className);
      }
   }

   /**
    * @deprecated
    */
01035    public ObjectInputStream deserialize(String className, ObjectName loaderName,
      byte[] data)
      throws InstanceNotFoundException, OperationsException, ReflectionException
   {
      try
      {
         ClassLoader cl = this.getClassLoader(loaderName);
         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(data), cl);
      }
      catch (IOException e)
      {
         throw new OperationsException("I/O exception deserializing: " + e.getMessage());
      }
   }

01050    public ClassLoader getClassLoaderFor(ObjectName name)
           throws InstanceNotFoundException
   {
      MBeanEntry entry = registry.get(name);
      checkMBeanPermission(entry.getResourceClassName(), null, name,
         "getClassLoaderFor");
      
      ClassLoader cl = entry.getClassLoader();
      if (cl == null)
         cl = entry.getResourceInstance().getClass().getClassLoader();
      if (cl == null)
         cl = ClassLoader.getSystemClassLoader();
      return cl;
   }

   /**
    * 
    * @param name The ObjectName of the ClassLoader. May be null, in which case
    * the MBean server's own ClassLoader is returned.
    * @return
    * @throws InstanceNotFoundException
    */ 
01072    public ClassLoader getClassLoader(ObjectName name)
           throws InstanceNotFoundException
   {
      Object loader = null;
      if( name == null )
      {
         checkMBeanPermission(null, null, name, "getClassLoader");
         loader = getClass().getClassLoader();
         if (loader == null)
            loader = ClassLoader.getSystemClassLoader();
      }
      else
      {
         MBeanEntry entry = registry.get(name);
         checkMBeanPermission(entry.getResourceClassName(), null, name,
            "getClassLoader");
         loader = entry.getResourceInstance();
      }

      if ((loader instanceof ClassLoader) == false)
         throw new InstanceNotFoundException("Not a classloader " + name);
      return (ClassLoader) loader;
   }

   /**
    * Retrieve the classloader repository for this mbean server
    *
    * @return the classloader repository
    */
01101    public ClassLoaderRepository getClassLoaderRepository()
   {
      checkMBeanPermission(null, null, null, "getClassLoaderRepository");

      // we don't need to synchronize, because this is the first thing we do in the constructor
      if (classLoaderRepository == null)
      {
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         String className = PropertyAccess.getProperty(LOADER_REPOSITORY_CLASS_PROPERTY, DEFAULT_LOADER_REPOSITORY_CLASS);
         PropertyAccess.setProperty(LOADER_REPOSITORY_CLASS_PROPERTY, className);

         try
         {
            Class repository = cl.loadClass(className);
            classLoaderRepository = (LoaderRepository) repository.newInstance();
         }
         catch (ClassNotFoundException e)
         {
            throw new Error("Cannot instantiate loader repository class: " + className);
         }
         catch (ClassCastException e)
         {
            throw new Error("Loader repository is not an instance of LoaderRepository: " + className);
         }
         catch (Exception e)
         {
            throw new Error("Error creating loader repository: " + e);
         }
      }

      return classLoaderRepository;
   }


   public void releaseServer()
   {
      //   shutdown the loader repository
//      try
//      {
//         invoke(new ObjectName(DEFAULT_LOADER_NAME),
//                "releaseLoaderRepository",
//                new Object[0],
//                new String[0] );
//      }
//      catch (Exception e)
//      {
//         log.error("Unable to shutdown loader repository");
//         e.printStackTrace();
//      }

      registry.releaseRegistry();
      listeners.removeAll();
      listeners = null;
      registry = null;
   }


   // Protected -----------------------------------------------------

   /**
    * Instantiate an object, the passed classloader is set as the
    * thread's context classloader for the duration of this method.
    *
    * @param className the class name of the object to instantiate
    * @param cl the thread classloader, pass null to use the ClassLoaderRepository
    * @param params the parameters for the constructor
    * @param signature the signature of the constructor
    * @exception ReflectionException wraps a ClassCastException or
    *            any Exception trying to invoke the constructor
    * @exception MBeanException wraps any exception thrown by the constructor
    * @exception RuntimeOperationsException Wraps an IllegalArgument for a
    *            null className
    */
01174    protected Object instantiate(String className, ClassLoader cl, Object[] params, String[] signature)
           throws ReflectionException, MBeanException
   {
      if (className == null)
         throw new RuntimeOperationsException(new IllegalArgumentException("Null className"));

      if (className.equals(""))
         throw new ReflectionException(new ClassNotFoundException("empty class name"));

      if (params == null)
         params = NOPARAMS;

      if (signature == null)
         signature = NOSIG;

      checkMBeanPermission(className, null, null, "instantiate");

      ClassLoader oldTCL = TCLAction.UTIL.getContextClassLoader();

      boolean setCl = false;
      try
      {
         Class clazz = null;
         if (cl != null)
         {
            if (cl != oldTCL)
            {
               setCl = true;
               TCLAction.UTIL.setContextClassLoader(cl);
            }
            clazz = cl.loadClass(className);
         }
         else
            clazz = classLoaderRepository.loadClass(className);

         Class[] sign = new Class[signature.length];
         for (int i = 0; i < signature.length; ++i)
         {
            if (LoaderRepository.getNativeClassForName(signature[i]) == null)
            {
               try
               {
                  if (cl != null)
                     sign[i] = cl.loadClass(signature[i]);
                  else
                     sign[i] = classLoaderRepository.loadClass(signature[i]);
               }
               catch (ClassNotFoundException e)
               {
                  throw new ReflectionException(e, "Constructor parameter class not found: " + signature[i]);
               }
            }
            else
            {
               sign[i] = LoaderRepository.getNativeClassForName(signature[i]);
            }
         }

         Constructor constructor = clazz.getConstructor(sign);
         return constructor.newInstance(params);
      }
      catch (Throwable t)
      {
         handleInstantiateExceptions(t, className);
         log.error("Unhandled exception instantiating class: " + className, t);
         return null;
      }
      finally
      {
         if (setCl)
            TCLAction.UTIL.setContextClassLoader(oldTCL);
      }
   }

   /**
    * Handles errors thrown during class instantiation
    */
01251    protected void handleInstantiateExceptions(Throwable t, String className)
           throws ReflectionException, MBeanException
   {
      if (t instanceof ReflectionException)
         throw (ReflectionException) t;

      else if (t instanceof ClassNotFoundException)
         throw new ReflectionException((Exception) t, "Class not found: " + className);

      else if (t instanceof InstantiationException)
         throw new ReflectionException((Exception) t, "Cannot instantiate: " + className);

      else if (t instanceof IllegalAccessException)
         throw new ReflectionException((Exception) t, "Illegal access to constructor: " + className);

      else if (t instanceof NoSuchMethodException)
         throw new ReflectionException((Exception) t, "Cannot find such a public constructor: " + className);

      else if (t instanceof SecurityException)
         throw new ReflectionException((Exception) t, "Can't access constructor for " + className);

      else if (t instanceof InvocationTargetException)
      {
         Throwable root = ((InvocationTargetException) t).getTargetException();

         if (root instanceof RuntimeException)
            throw new RuntimeMBeanException((RuntimeException) root, className + " constructor has thrown an exception: " + root.toString());
         else if (root instanceof Error)
            throw new RuntimeErrorException((Error) root, className + " constructor has thrown an error: " + root.toString());
         else if (root instanceof Exception)
            throw new MBeanException((Exception) root, className + " constructor has thrown an exception: " + root.toString());

         throw new Error("Something went wrong with handling the exception from " + className + " default constructor.");
      }

      else if (t instanceof ExceptionInInitializerError)
      {
         Throwable root = ((ExceptionInInitializerError) t).getException();

         // the root cause can be only a runtime exception
         if (root instanceof RuntimeException)
            throw new RuntimeMBeanException((RuntimeException) root, "Exception in class " + className + " static initializer: " + root.toString());
         else
         // shouldn't get here
            throw new Error("ERROR: it turns out the root cause is not always a runtime exception!");
      }

      else if (t instanceof IllegalArgumentException)
      {
         // if mismatch between constructor instance args and supplied args -- shouldn't happen
         throw new Error("Error in the server: mismatch between expected constructor arguments and supplied arguments.");
      }

      else if (t instanceof Error)
      {
         throw new RuntimeErrorException((Error) t, "instantiating " + className + " failed: " + t.toString());
      }
   }


   /**
    * Register an MBean<p>
    *
    * The classloader is used as the thread context classloader during
    * access to the mbean and it's interceptors
    *
    * @param mbean the mbean to register
    * @param name the object name to register
    * @param loaderName the object name of a class loader also used as
    *        as the MBeans TCL
    * @exception InstanceAlreadyExistsException when already registered
    * @exception MBeanRegistrationException when
    *            preRegister(MBeanServer, ObjectName) throws an exception
    * @exception NotCompliantMBeanException when the object is not an MBean
    */
01326    protected ObjectInstance registerMBean(Object mbean, ObjectName name, ObjectName loaderName)
           throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException
   {
      ClassLoader cl = null;

      //  If the loader name is null, the ClassLoader that loaded the MBean Server will be used.
      if (loaderName == null)
      {
         cl = getClass().getClassLoader();
         if (cl == null)
            cl = ClassLoader.getSystemClassLoader();
      }
      else
      {
         try
         {
            cl = (ClassLoader) registry.get(loaderName).getResourceInstance();
         }
         catch (ClassCastException e)
         {
            throw new ReflectionException(e, loaderName + " is not a class loader.");
         }
      }

      return registerMBean(mbean, name, cl);
   }

   /**
    * Register an MBean<p>
    *
    * The classloader is used as the thread context classloader during
    * access to the mbean and it's interceptors
    *
    * @param object the mbean to register
    * @param name the object name to register
    * @param cl the thread classloader, pass null for the current one
    * @exception InstanceAlreadyExistsException when already registered
    * @exception MBeanRegistrationException when
    *            preRegister(MBeanServer, ObjectName) throws an exception
    * @exception NotCompliantMBeanException when the object is not an MBean
    */
01367    protected ObjectInstance registerMBean(Object object, ObjectName name,
                                          ClassLoader cl)
           throws InstanceAlreadyExistsException,
           MBeanRegistrationException,
           NotCompliantMBeanException
   {
      final Class objectClass = object.getClass();
      String className = objectClass.getName();

      // Check that the caller has the ability to create/register mbeans
      checkMBeanPermission(className, null, name, "registerMBean");

      // Check that the mbean class is from a trusted source
      if( System.getSecurityManager() != null )
      {
         ProtectionDomain pd = (ProtectionDomain) AccessController.doPrivileged(
            new PrivilegedAction()
            {
               public Object run()
               {
                  return objectClass.getProtectionDomain();
               }
            }
         );
         if( pd != null )
         {
            MBeanTrustPermission p = new MBeanTrustPermission("register");
            if( pd.implies(p) == false )
            {
               String msg = "MBeanTrustPermission(register) not implied by "
                  + "protection domain of mbean class: "+className+", pd: "+pd;
               throw new SecurityException(msg);
            }
         }
      }

      HashMap valueMap = null;
      if (cl != null)
      {
         valueMap = new HashMap();
         valueMap.put(CLASSLOADER, cl);
      }

      try
      {
         final Object[] args = {object, name, valueMap};
         final String[] sig = {Object.class.getName(),
            ObjectName.class.getName(), Map.class.getName()};
         try
         {
            ObjectInstance oi = (ObjectInstance) AccessController.doPrivileged(
               new PrivilegedExceptionAction()
               {
                  public Object run() throws Exception
                  {
                     return invoke(new ObjectName(MBEAN_REGISTRY),
                        "registerMBean", args, sig);
                  }
               }
            );
            return oi;
         }
         catch(PrivilegedActionException e)
         {
            throw e.getException();
         }
      }
      catch (Throwable t)
      {
         Throwable result = JMXExceptionDecoder.decodeToJMXException(t);
         if (result instanceof InstanceAlreadyExistsException)
            throw (InstanceAlreadyExistsException) result;
         if (result instanceof MBeanRegistrationException)
            throw (MBeanRegistrationException) result;
         if (result instanceof NotCompliantMBeanException)
            throw (NotCompliantMBeanException) result;
         if ( result instanceof JMRuntimeException )
            throw (JMRuntimeException) result;
         if (result instanceof RuntimeException)
            throw new RuntimeMBeanException((RuntimeException) result);
         if (result instanceof Error)
            throw new RuntimeErrorException((Error) result);

         // for some other reason, registration failed
         throw new MBeanRegistrationException(new InvocationTargetException(t), "Cannot register MBean");
      }
   }

   // Private -------------------------------------------------------

   /**
    * Query an MBean against the query
    *
    * @param objectName the object name of the mbean to check
    * @param queryExp the query expression to test
    * @return true when the query applies to the MBean or the query is null,
    *         false otherwise.
    */
01465    protected boolean queryMBean(ObjectName objectName, QueryExp queryExp)
   {
      if (queryExp == null)
         return true;

      try
      {
         return queryExp.apply(objectName);
      }
      catch (Exception e)
      {
         return false;
      }
   }


   protected MBeanRegistry createRegistry(String defaultDomain)
   {
      // Find the registry implementation class: can be configured via
      // MBEAN_REGISTRY_CLASS_PROPERTY by the client -- if not found use
      // the class defined in DEFAULT_MBEAN_REGISTRY_CLASS (see ServerConstants)
      String registryClass = PropertyAccess.getProperty(ServerConstants.MBEAN_REGISTRY_CLASS_PROPERTY,
              ServerConstants.DEFAULT_MBEAN_REGISTRY_CLASS);

      try
      {
         // Try loading registry class via thread context classloader
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         Class clazz = cl.loadClass(registryClass);

         // retrieve the constructor <init>(MBeanServer srvr, String defaultDomain, ClassLoaderRepository clr)
         Constructor constructor = clazz.getConstructor(new Class[] {MBeanServer.class, String.class, ClassLoaderRepository.class});

         // instantiate registry
         return (MBeanRegistry) constructor.newInstance(new Object[] {outer, defaultDomain, classLoaderRepository});
      }
      // Any exception preventing the registry to be created will cause the agent to fail.
      // However, try to give detailed exception messages to indicate config errors.
      catch (ClassNotFoundException e)
      {
         throw new NestedRuntimeException("The MBean registry implementation class " + registryClass +
                 " was not found: ", e);
      }
      catch (NoSuchMethodException e)
      {
         throw new NestedRuntimeException("The MBean registry implementation class " + registryClass +
                 " must contain a default <init>(MBeanServer srvr, String domain) " +
                 " constructor.", e);
      }
      catch (InstantiationException e)
      {
         throw new NestedRuntimeException("Cannot instantiate class " + registryClass + ": ", e);
      }
      catch (IllegalAccessException e)
      {
         throw new NestedRuntimeException("Unable to create the MBean registry instance. Illegal access " +
                 "to class " + registryClass + " constructor: ", e);
      }
      catch (InvocationTargetException e)
      {
         throw new NestedRuntimeException("Unable to create the MBean registry instance. Class " + registryClass +
                 " has raised an exception in constructor: ", e.getTargetException());
      }
   }


   // Private -------------------------------------------------------
   
   // FIXME: externalize this
   private ModelMBeanInfo getRegistryManagementInterface()
   {
      final boolean READABLE = true;
      final boolean WRITABLE = true;
      final boolean BOOLEAN = true;

      // Default Domain attribute
      DescriptorSupport descDefaultDomain = new DescriptorSupport();
      descDefaultDomain.setField("name", "DefaultDomain");
      descDefaultDomain.setField("descriptorType", "attribute");
      descDefaultDomain.setField("displayName", "Default Domain");
      descDefaultDomain.setField("default", getDefaultDomain());
      descDefaultDomain.setField("currencyTimeLimit", "-1");
      ModelMBeanAttributeInfo defaultDomainInfo =
              new ModelMBeanAttributeInfo
                      ("DefaultDomain", String.class.getName(),
                              "The domain to use when an object name has no domain",
                              READABLE, !WRITABLE, !BOOLEAN,
                              descDefaultDomain);

      // Size attribute
      DescriptorSupport descSize = new DescriptorSupport();
      descSize.setField("name", "Size");
      descSize.setField("descriptorType", "attribute");
      descSize.setField("displayName", "Size");
      descSize.setField("getMethod", "getSize");
      ModelMBeanAttributeInfo sizeInfo =
              new ModelMBeanAttributeInfo
                      ("Size", Integer.TYPE.getName(),
                              "The number of MBeans registered in the MBean Server",
                              READABLE, !WRITABLE, !BOOLEAN,
                              descSize);

      // registerMBean operation
      DescriptorSupport descRegisterMBean = new DescriptorSupport();
      descRegisterMBean.setField("name", "registerMBean");
      descRegisterMBean.setField("descriptorType", "operation");
      descRegisterMBean.setField("role", "operation");
      MBeanParameterInfo[] registerMBeanParms =
              new MBeanParameterInfo[]
              {
                 new MBeanParameterInfo
                         ("Resource",
                                 Object.class.getName(),
                                 "A compliant MBean to be registered in the MBean Server"),
                 new MBeanParameterInfo
                         ("ObjectName",
                                 ObjectName.class.getName(),
                                 "The object name of the MBean"),
                 new MBeanParameterInfo
                         ("ValueMap",
                                 Map.class.getName(),
                                 "Values associated with the registration"),
              };
      ModelMBeanOperationInfo registerMBeanInfo =
              new ModelMBeanOperationInfo
                      ("registerMBean",
                              "Adds an MBean in the MBeanServer",
                              registerMBeanParms,
                              ObjectInstance.class.getName(),
                              ModelMBeanOperationInfo.ACTION_INFO,
                              descRegisterMBean);

      // unregisterMBean operation
      DescriptorSupport descUnregisterMBean = new DescriptorSupport();
      descUnregisterMBean.setField("name", "unregisterMBean");
      descUnregisterMBean.setField("descriptorType", "operation");
      descUnregisterMBean.setField("role", "operation");
      MBeanParameterInfo[] unregisterMBeanParms =
              new MBeanParameterInfo[]
              {
                 new MBeanParameterInfo
                         ("ObjectName",
                                 ObjectName.class.getName(),
                                 "The object name of the MBean to remove")
              };
      ModelMBeanOperationInfo unregisterMBeanInfo =
              new ModelMBeanOperationInfo
                      ("unregisterMBean",
                              "Removes an MBean from the MBeanServer",
                              unregisterMBeanParms,
                              Void.TYPE.getName(),
                              ModelMBeanOperationInfo.ACTION,
                              descUnregisterMBean);

      // getSize operation
      DescriptorSupport descGetSize = new DescriptorSupport();
      descGetSize.setField("name", "getSize");
      descGetSize.setField("descriptorType", "operation");
      descGetSize.setField("role", "getter");
      MBeanParameterInfo[] getSizeParms = new MBeanParameterInfo[0];
      ModelMBeanOperationInfo getSizeInfo =
              new ModelMBeanOperationInfo
                      ("getSize",
                              "Gets the number of MBeans registered",
                              getSizeParms,
                              Integer.TYPE.getName(),
                              ModelMBeanOperationInfo.INFO,
                              descGetSize);

      // get operation
      DescriptorSupport descGet = new DescriptorSupport();
      descGet.setField("name", "get");
      descGet.setField("descriptorType", "operation");
      descGet.setField("role", "operation");
      MBeanParameterInfo[] getParam = new MBeanParameterInfo[1];
      getParam[0] = new MBeanParameterInfo("ObjectName", ObjectName.class.getName(), "object name to find");
      ModelMBeanOperationInfo getInfo =
              new ModelMBeanOperationInfo
                      ("get",
                              "Gets the MBeanEntry for a given ObjectName",
                              getParam,
                              MBeanEntry.class.getName(),
                              ModelMBeanOperationInfo.INFO,
                              descGet);

      // getValue operation
      DescriptorSupport descGetValue = new DescriptorSupport();
      descGetValue.setField("name", "getValue");
      descGetValue.setField("descriptorType", "operation");
      descGetValue.setField("role", "operation");
      MBeanParameterInfo[] getValueParms = new MBeanParameterInfo[]
      {
         new MBeanParameterInfo
                 ("ObjectName",
                         ObjectName.class.getName(),
                         "The object name of the registered MBean"),
         new MBeanParameterInfo
                 ("Key",
                         String.class.getName(),
                         "The key to the value stored")
      };
      ModelMBeanOperationInfo getValueInfo =
              new ModelMBeanOperationInfo
                      ("getValue",
                              "Get a value stored in the MBean's registration",
                              getValueParms,
                              Object.class.getName(),
                              ModelMBeanOperationInfo.INFO,
                              descGetValue);

      // Construct the modelmbean
      DescriptorSupport descMBean = new DescriptorSupport();
      descMBean.setField("name", RequiredModelMBeanInstantiator.getClassName());
      descMBean.setField("descriptorType", "MBean");
      descMBean.setField("displayName", "MBeanServer Registry");
      ModelMBeanAttributeInfo[] attrInfo = new ModelMBeanAttributeInfo[]
      {
         defaultDomainInfo,
         sizeInfo
      };
      ModelMBeanConstructorInfo[] ctorInfo = null;
      ModelMBeanOperationInfo[] opInfo = new ModelMBeanOperationInfo[]
      {
         registerMBeanInfo,
         unregisterMBeanInfo,
         getSizeInfo,
         getValueInfo,
         getInfo
      };
      ModelMBeanNotificationInfo[] notifyInfo = null;
      ModelMBeanInfoSupport info = new ModelMBeanInfoSupport
              (RequiredModelMBeanInstantiator.getClassName(),
                      "Managed Bean Registry",
                      attrInfo,
                      ctorInfo,
                      opInfo,
                      notifyInfo,
                      descMBean);

      return info;
   }

   private void checkMBeanPermission(String className, String member,
      ObjectName objectName, String action)
   {
      SecurityManager sm = System.getSecurityManager();
      if( sm != null )
      {
         MBeanPermission p = new MBeanPermission(className, member, objectName,
            action);
         sm.checkPermission(p);
      }
   }
   
   // Object overrides ----------------------------------------------
   
   /**
    * Simple toString() revealing default domain
    */
01724    public String toString()
   {
      return super.toString() + "[ defaultDomain='" + this.getDefaultDomain() + "' ]";
   }      
}

Generated by  Doxygen 1.6.0   Back to index