mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			818 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			818 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Java
		
	
	
	
/* ManagementFactory.java - Factory for obtaining system beans.
 | 
						|
   Copyright (C) 2006 Free Software Foundation
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath 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
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
package java.lang.management;
 | 
						|
 | 
						|
import gnu.classpath.SystemProperties;
 | 
						|
 | 
						|
import gnu.java.lang.management.ClassLoadingMXBeanImpl;
 | 
						|
import gnu.java.lang.management.CompilationMXBeanImpl;
 | 
						|
import gnu.java.lang.management.GarbageCollectorMXBeanImpl;
 | 
						|
import gnu.java.lang.management.OperatingSystemMXBeanImpl;
 | 
						|
import gnu.java.lang.management.MemoryMXBeanImpl;
 | 
						|
import gnu.java.lang.management.MemoryManagerMXBeanImpl;
 | 
						|
import gnu.java.lang.management.MemoryPoolMXBeanImpl;
 | 
						|
import gnu.java.lang.management.RuntimeMXBeanImpl;
 | 
						|
import gnu.java.lang.management.ThreadMXBeanImpl;
 | 
						|
 | 
						|
import java.io.IOException;
 | 
						|
 | 
						|
import java.lang.reflect.InvocationHandler;
 | 
						|
import java.lang.reflect.Method;
 | 
						|
import java.lang.reflect.Proxy;
 | 
						|
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.HashMap;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
 | 
						|
import java.util.logging.LogManager;
 | 
						|
 | 
						|
import javax.management.Attribute;
 | 
						|
import javax.management.InstanceAlreadyExistsException;
 | 
						|
import javax.management.MBeanRegistrationException;
 | 
						|
import javax.management.MBeanServer;
 | 
						|
import javax.management.MBeanServerConnection;
 | 
						|
import javax.management.MBeanServerFactory;
 | 
						|
import javax.management.MalformedObjectNameException;
 | 
						|
import javax.management.NotCompliantMBeanException;
 | 
						|
import javax.management.NotificationEmitter;
 | 
						|
import javax.management.NotificationFilter;
 | 
						|
import javax.management.NotificationListener;
 | 
						|
import javax.management.ObjectName;
 | 
						|
 | 
						|
import javax.management.openmbean.CompositeData;
 | 
						|
import javax.management.openmbean.TabularData;
 | 
						|
 | 
						|
/**
 | 
						|
 * <p>
 | 
						|
 * Provides access to the system's management beans via a series
 | 
						|
 * of static methods.
 | 
						|
 * </p>
 | 
						|
 * <p>
 | 
						|
 * An instance of a system management bean can be obtained by
 | 
						|
 * using one of the following methods:
 | 
						|
 * </p>
 | 
						|
 * <ol>
 | 
						|
 * <li>Calling the appropriate static method of this factory.
 | 
						|
 * </li>
 | 
						|
 * <li>Using the platform {@link javax.management.MBeanServer}
 | 
						|
 * to access the beans locally, or an
 | 
						|
 * {@link javax.management.MBeanServerConnection} for remote
 | 
						|
 * access.  The attributes and operations use the limited
 | 
						|
 * range of data types specified below.</li>
 | 
						|
 * </ol>
 | 
						|
 * <h2>Open Data Types</h2>
 | 
						|
 * <p>
 | 
						|
 * The data types used by the management beans are restricted
 | 
						|
 * to <emph>open</emph> data types to aid interoperability.  This
 | 
						|
 * allows the beans to be accessed remotely, including from non-Java
 | 
						|
 * clients.  Below is a table which lists the types used by the beans
 | 
						|
 * on the left, and the types they are converted to when returned via
 | 
						|
 * a bean server on the right.  Type information is provided for each
 | 
						|
 * bean by obtaining its instance of {@link javax.management.MBeanInfo}.
 | 
						|
 * </p>
 | 
						|
 * <table>
 | 
						|
 * <th><td>Data Type Used</td><td>Data Type Returned</td></th>
 | 
						|
 * <tr>
 | 
						|
 * <td>Primitive types (<code>int</code>, <code>char</code>, etc.)</td>
 | 
						|
 * <td>Same</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>Wrapper classes ({@link{java.lang.Integer},
 | 
						|
 * @link{java.lang.Character}, etc.)</td>
 | 
						|
 * <td>Same</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>An {@link java.lang.Enum}</td>
 | 
						|
 * <td>The <code>name</code> of the enumeration constant</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>An array of type <code>E</code></td>
 | 
						|
 * <td>An array of the same dimensions with this mapping applied
 | 
						|
 * to <code>E</code>.</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>A class with `getter' methods and a
 | 
						|
 * <code>from({@link javax.management.openmbean.CompositeData})</code>
 | 
						|
 * method.</td>
 | 
						|
 * <td>The equivalent {@link javax.management.openmbean.CompositeData}
 | 
						|
 * instance, specified by the <code>from</code> method.</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>A map with keys of type <code>K</code> and values of
 | 
						|
 * type <code>V</code>.</td>
 | 
						|
 * <td>A {@link javax.management.openmbean.TabularData} instance,
 | 
						|
 * with the row type containing two items, <code>"key"</code> and
 | 
						|
 * <code>"value"</code> with the types <code>K</code> and <code>V</code>
 | 
						|
 * respectively (with translation applied).</td>
 | 
						|
 * </tr><tr>
 | 
						|
 * <td>A list of type <code>E</code>.</td>
 | 
						|
 * <td>An array with this mapping applied to <code>E</code>.</td>
 | 
						|
 * </tr></table>
 | 
						|
 *
 | 
						|
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
 * @since 1.5
 | 
						|
 */
 | 
						|
public class ManagementFactory
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the class loading bean.
 | 
						|
   */
 | 
						|
  public static final String CLASS_LOADING_MXBEAN_NAME =
 | 
						|
    "java.lang:type=ClassLoading";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the compilation bean.
 | 
						|
   */
 | 
						|
  public static final String COMPILATION_MXBEAN_NAME =
 | 
						|
    "java.lang:type=Compilation";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The domain for the garbage collecting beans.
 | 
						|
   */
 | 
						|
  public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE =
 | 
						|
    "java.lang:type=GarbageCollector";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The domain for the memory manager beans.
 | 
						|
   */
 | 
						|
  public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE =
 | 
						|
    "java.lang:type=MemoryManager";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the memory bean.
 | 
						|
   */
 | 
						|
  public static final String MEMORY_MXBEAN_NAME =
 | 
						|
    "java.lang:type=Memory";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The domain for the memory pool beans.
 | 
						|
   */
 | 
						|
  public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE =
 | 
						|
    "java.lang:type=MemoryPool";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the operating system bean.
 | 
						|
   */
 | 
						|
  public static final String OPERATING_SYSTEM_MXBEAN_NAME =
 | 
						|
    "java.lang:type=OperatingSystem";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the runtime bean.
 | 
						|
   */
 | 
						|
  public static final String RUNTIME_MXBEAN_NAME =
 | 
						|
    "java.lang:type=Runtime";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object name for the threading bean.
 | 
						|
   */
 | 
						|
  public static final String THREAD_MXBEAN_NAME =
 | 
						|
    "java.lang:type=Threading";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The operating system management bean.
 | 
						|
   */
 | 
						|
  private static OperatingSystemMXBean osBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The runtime management bean.
 | 
						|
   */
 | 
						|
  private static RuntimeMXBean runtimeBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The class loading management bean.
 | 
						|
   */
 | 
						|
  private static ClassLoadingMXBean classLoadingBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The thread bean.
 | 
						|
   */
 | 
						|
  private static ThreadMXBean threadBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The memory bean.
 | 
						|
   */
 | 
						|
  private static MemoryMXBean memoryBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The compilation bean (may remain null).
 | 
						|
   */
 | 
						|
  private static CompilationMXBean compilationBean;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The platform server.
 | 
						|
   */
 | 
						|
  private static MBeanServer platformServer;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Private constructor to prevent instance creation.
 | 
						|
   */
 | 
						|
  private ManagementFactory() {}
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the operating system management bean for the
 | 
						|
   * operating system on which the virtual machine is running.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link OperatingSystemMXBean} for
 | 
						|
   *         the underlying operating system.
 | 
						|
   */
 | 
						|
  public static OperatingSystemMXBean getOperatingSystemMXBean()
 | 
						|
  {
 | 
						|
    if (osBean == null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          osBean = new OperatingSystemMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "operating system bean is not a " +
 | 
						|
                                  "compliant management bean.");
 | 
						|
        }
 | 
						|
    return osBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the runtime management bean for the
 | 
						|
   * running virtual machine.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link RuntimeMXBean} for
 | 
						|
   *         this virtual machine.
 | 
						|
   */
 | 
						|
  public static RuntimeMXBean getRuntimeMXBean()
 | 
						|
  {
 | 
						|
    if (runtimeBean == null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          runtimeBean = new RuntimeMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "runtime bean is not a compliant " +
 | 
						|
                                  "management bean.");
 | 
						|
        }
 | 
						|
    return runtimeBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the class loading management bean for the
 | 
						|
   * running virtual machine.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link ClassLoadingMXBean} for
 | 
						|
   *         this virtual machine.
 | 
						|
   */
 | 
						|
  public static ClassLoadingMXBean getClassLoadingMXBean()
 | 
						|
  {
 | 
						|
    if (classLoadingBean == null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          classLoadingBean = new ClassLoadingMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "class loading bean is not a " +
 | 
						|
                                  "compliant management bean.");
 | 
						|
        }
 | 
						|
    return classLoadingBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the thread management bean for the running
 | 
						|
   * virtual machine.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link ThreadMXBean} for
 | 
						|
   *         this virtual machine.
 | 
						|
   */
 | 
						|
  public static ThreadMXBean getThreadMXBean()
 | 
						|
  {
 | 
						|
    if (threadBean == null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          threadBean = new ThreadMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "thread bean is not a compliant " +
 | 
						|
                                  "management bean.");
 | 
						|
        }
 | 
						|
    return threadBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the memory management bean for the running
 | 
						|
   * virtual machine.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link MemoryMXBean} for
 | 
						|
   *         this virtual machine.
 | 
						|
   */
 | 
						|
  public static MemoryMXBean getMemoryMXBean()
 | 
						|
  {
 | 
						|
    if (memoryBean == null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          memoryBean = new MemoryMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "memory bean is not a compliant " +
 | 
						|
                                  "management bean.");
 | 
						|
        }
 | 
						|
    return memoryBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the compilation bean for the running
 | 
						|
   * virtual machine, if supported.  Otherwise,
 | 
						|
   * it returns <code>null</code>.
 | 
						|
   *
 | 
						|
   * @return an instance of {@link CompilationMXBean} for
 | 
						|
   *         this virtual machine, or <code>null</code>
 | 
						|
   *         if the virtual machine doesn't include
 | 
						|
   *         a Just-In-Time (JIT) compiler.
 | 
						|
   */
 | 
						|
  public static CompilationMXBean getCompilationMXBean()
 | 
						|
  {
 | 
						|
    if (compilationBean == null &&
 | 
						|
        SystemProperties.getProperty("gnu.java.compiler.name") != null)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          compilationBean = new CompilationMXBeanImpl();
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "compilation bean is not a compliant " +
 | 
						|
                                  "management bean.");
 | 
						|
        }
 | 
						|
    return compilationBean;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the memory pool beans for the running
 | 
						|
   * virtual machine.  These may change during the course
 | 
						|
   * of execution.
 | 
						|
   *
 | 
						|
   * @return a list of memory pool beans, one for each pool.
 | 
						|
   */
 | 
						|
  public static List<MemoryPoolMXBean> getMemoryPoolMXBeans()
 | 
						|
  {
 | 
						|
    List<MemoryPoolMXBean> poolBeans =
 | 
						|
      new ArrayList<MemoryPoolMXBean>();
 | 
						|
    String[] names = VMManagementFactory.getMemoryPoolNames();
 | 
						|
    for (int a = 0; a < names.length; ++a)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          poolBeans.add(new MemoryPoolMXBeanImpl(names[a]));
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "memory pool bean, " + a + ", is " +
 | 
						|
                                  "not a compliant management bean.");
 | 
						|
        }
 | 
						|
    return poolBeans;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the memory manager beans for the running
 | 
						|
   * virtual machine.  These may change during the course
 | 
						|
   * of execution.
 | 
						|
   *
 | 
						|
   * @return a list of memory manager beans, one for each manager.
 | 
						|
   */
 | 
						|
  public static List<MemoryManagerMXBean> getMemoryManagerMXBeans()
 | 
						|
  {
 | 
						|
    List<MemoryManagerMXBean> managerBeans =
 | 
						|
      new ArrayList<MemoryManagerMXBean>();
 | 
						|
    String[] names = VMManagementFactory.getMemoryManagerNames();
 | 
						|
    for (int a = 0; a < names.length; ++a)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          managerBeans.add(new MemoryManagerMXBeanImpl(names[a]));
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "memory manager bean, " + a + ", is " +
 | 
						|
                                  "not a compliant management bean.");
 | 
						|
        }
 | 
						|
    managerBeans.addAll(getGarbageCollectorMXBeans());
 | 
						|
    return managerBeans;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the garbage collector beans for the running
 | 
						|
   * virtual machine.  These may change during the course
 | 
						|
   * of execution.
 | 
						|
   *
 | 
						|
   * @return a list of garbage collector beans, one for each pool.
 | 
						|
   */
 | 
						|
  public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans()
 | 
						|
  {
 | 
						|
    List<GarbageCollectorMXBean> gcBeans =
 | 
						|
      new ArrayList<GarbageCollectorMXBean>();
 | 
						|
    String[] names = VMManagementFactory.getGarbageCollectorNames();
 | 
						|
    for (int a = 0; a < names.length; ++a)
 | 
						|
      try
 | 
						|
        {
 | 
						|
          gcBeans.add(new GarbageCollectorMXBeanImpl(names[a]));
 | 
						|
        }
 | 
						|
      catch (NotCompliantMBeanException e)
 | 
						|
        {
 | 
						|
          throw new InternalError("The GNU implementation of the " +
 | 
						|
                                  "garbage collector bean, " + a +
 | 
						|
                                  ", is not a compliant management " +
 | 
						|
                                  "bean.");
 | 
						|
        }
 | 
						|
    return gcBeans;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns the platform {@link javax.management.MBeanServer}.  On the
 | 
						|
   * first call to this method, a server instance is retrieved from
 | 
						|
   * the {@link javax.management.MBeanServerFactory} and each of the
 | 
						|
   * beans are registered with it.  Subsequent calls return the existing
 | 
						|
   * instance.  If the property <code>javax.management.builder.initial</code>
 | 
						|
   * is set, its value will be used as the name of the class which is used
 | 
						|
   * to provide the server instance.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * It is recommended that the platform server is used for other beans as
 | 
						|
   * well, in order to simplify their discovery and publication.  Name conflicts
 | 
						|
   * should be avoided.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @return the platform {@link javax.management.MBeanServer}
 | 
						|
   * @throws SecurityException if a security manager exists and the
 | 
						|
   *                           caller's permissions don't imply {@link
 | 
						|
   *                           MBeanServerPermission(String)}("createMBeanServer")
 | 
						|
   * @see javax.management.MBeanServerFactory
 | 
						|
   * @see javax.management.MBeanServerFactory#createMBeanServer()
 | 
						|
   */
 | 
						|
  public static MBeanServer getPlatformMBeanServer()
 | 
						|
  {
 | 
						|
    if (platformServer == null)
 | 
						|
      {
 | 
						|
        platformServer = MBeanServerFactory.createMBeanServer();
 | 
						|
        try
 | 
						|
          {
 | 
						|
            platformServer.registerMBean(getOperatingSystemMXBean(),
 | 
						|
                                         new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME));
 | 
						|
            platformServer.registerMBean(getRuntimeMXBean(),
 | 
						|
                                         new ObjectName(RUNTIME_MXBEAN_NAME));
 | 
						|
            platformServer.registerMBean(getClassLoadingMXBean(),
 | 
						|
                                         new ObjectName(CLASS_LOADING_MXBEAN_NAME));
 | 
						|
            platformServer.registerMBean(getThreadMXBean(),
 | 
						|
                                         new ObjectName(THREAD_MXBEAN_NAME));
 | 
						|
            platformServer.registerMBean(getMemoryMXBean(),
 | 
						|
                                         new ObjectName(MEMORY_MXBEAN_NAME));
 | 
						|
            CompilationMXBean compBean = getCompilationMXBean();
 | 
						|
            if (compBean != null)
 | 
						|
              platformServer.registerMBean(compBean,
 | 
						|
                                           new ObjectName(COMPILATION_MXBEAN_NAME));
 | 
						|
            Iterator beans = getMemoryPoolMXBeans().iterator();
 | 
						|
            while (beans.hasNext())
 | 
						|
              {
 | 
						|
                MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
 | 
						|
                platformServer.registerMBean(bean,
 | 
						|
                                             new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
 | 
						|
                                                            ",name=" +
 | 
						|
                                                            bean.getName()));
 | 
						|
              }
 | 
						|
            beans = getMemoryManagerMXBeans().iterator();
 | 
						|
            while (beans.hasNext())
 | 
						|
              {
 | 
						|
                MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next();
 | 
						|
                platformServer.registerMBean(bean,
 | 
						|
                                             new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE +
 | 
						|
                                                            ",name=" +
 | 
						|
                                                            bean.getName()));
 | 
						|
              }
 | 
						|
            beans = getGarbageCollectorMXBeans().iterator();
 | 
						|
            while (beans.hasNext())
 | 
						|
              {
 | 
						|
                GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next();
 | 
						|
                platformServer.registerMBean(bean,
 | 
						|
                                             new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
 | 
						|
                                                            ",name=" +
 | 
						|
                                                            bean.getName()));
 | 
						|
              }
 | 
						|
            platformServer.registerMBean(LogManager.getLoggingMXBean(),
 | 
						|
                                         new ObjectName(LogManager.LOGGING_MXBEAN_NAME));
 | 
						|
          }
 | 
						|
        catch (InstanceAlreadyExistsException e)
 | 
						|
          {
 | 
						|
            throw (Error)
 | 
						|
              (new InternalError("One of the management beans is " +
 | 
						|
                                 "already registered.").initCause(e));
 | 
						|
          }
 | 
						|
        catch (MBeanRegistrationException e)
 | 
						|
          {
 | 
						|
            throw (Error)
 | 
						|
              (new InternalError("One of the management beans' preRegister " +
 | 
						|
                                 "methods threw an exception.").initCause(e));
 | 
						|
          }
 | 
						|
        catch (NotCompliantMBeanException e)
 | 
						|
          {
 | 
						|
            throw (Error)
 | 
						|
              (new InternalError("One of the management beans is " +
 | 
						|
                                 "not compliant.").initCause(e));
 | 
						|
          }
 | 
						|
        catch (MalformedObjectNameException e)
 | 
						|
          {
 | 
						|
            throw (Error)
 | 
						|
              (new InternalError("The object name of a management bean is " +
 | 
						|
                                 "not compliant.").initCause(e));
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return platformServer;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a proxy for the specified platform bean.  A proxy object is created
 | 
						|
   * using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
 | 
						|
   * new Class[] { mxbeanInterface }, handler)</code>.  The
 | 
						|
   * {@link javax.management.NotificationEmitter} class is also added to the
 | 
						|
   * array if the bean provides notifications.  <code>handler</code> refers
 | 
						|
   * to the invocation handler which forwards calls to the connection, and
 | 
						|
   * also provides translation between the Java data types used in the
 | 
						|
   * bean interfaces and the open data types, as specified in the description
 | 
						|
   * of this class.  It is this translation that makes the
 | 
						|
   * usual {@link javax.management.MBeanServerInvocationHandler} inappropriate
 | 
						|
   * for providing such a proxy.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * <strong>Note</strong>: use of the proxy may result in
 | 
						|
   * {@link java.io.IOException}s from the underlying {@link MBeanServerConnection}
 | 
						|
   * and a {@link java.io.InvalidObjectException} if enum constants
 | 
						|
   * used on the client and the server don't match.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param connection the server connection to use to access the bean.
 | 
						|
   * @param mxbeanName the {@link javax.management.ObjectName} of the
 | 
						|
   *                   bean to provide a proxy for.
 | 
						|
   * @param mxbeanInterface the interface for the bean being proxied.
 | 
						|
   * @return a proxy for the specified bean.
 | 
						|
   * @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid
 | 
						|
   *                                  {@link javax.management.ObjectName},
 | 
						|
   *                                  the interface and name do not match the
 | 
						|
   *                                  same bean, the name does not refer to a
 | 
						|
   *                                  platform bean or the bean is not registered
 | 
						|
   *                                  with the server accessed by <code>connection</code>.
 | 
						|
   * @throws IOException if the connection throws one.
 | 
						|
   */
 | 
						|
  public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
 | 
						|
                                             String mxbeanName,
 | 
						|
                                             Class<T> mxbeanInterface)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
 | 
						|
          mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
 | 
						|
          mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
 | 
						|
          mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
 | 
						|
          mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
 | 
						|
          mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
 | 
						|
          mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
 | 
						|
          mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
 | 
						|
          mxbeanName.equals(THREAD_MXBEAN_NAME)))
 | 
						|
      {
 | 
						|
        throw new IllegalArgumentException("The named bean, " + mxbeanName +
 | 
						|
                                           ", is not a platform name.");
 | 
						|
      }
 | 
						|
    if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != ClassLoadingMXBean.class) ||
 | 
						|
        (mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != CompilationMXBean.class) ||
 | 
						|
        (mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
 | 
						|
         mxbeanInterface != GarbageCollectorMXBean.class) ||
 | 
						|
        (mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
 | 
						|
         mxbeanInterface != MemoryManagerMXBean.class) ||
 | 
						|
        (mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != MemoryMXBean.class) ||
 | 
						|
        (mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
 | 
						|
         mxbeanInterface != MemoryPoolMXBean.class) ||
 | 
						|
        (mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != OperatingSystemMXBean.class) ||
 | 
						|
        (mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != RuntimeMXBean.class) ||
 | 
						|
        (mxbeanName.equals(THREAD_MXBEAN_NAME) &&
 | 
						|
         mxbeanInterface != ThreadMXBean.class))
 | 
						|
      throw new IllegalArgumentException("The interface, " + mxbeanInterface +
 | 
						|
                                         ", does not match the bean, " + mxbeanName);
 | 
						|
    ObjectName bean;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        bean = new ObjectName(mxbeanName);
 | 
						|
      }
 | 
						|
    catch (MalformedObjectNameException e)
 | 
						|
      {
 | 
						|
        throw new IllegalArgumentException("The named bean is invalid.");
 | 
						|
      }
 | 
						|
    if (!(connection.isRegistered(bean)))
 | 
						|
      throw new IllegalArgumentException("The bean is not registered on this connection.");
 | 
						|
    Class[] interfaces;
 | 
						|
    if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
 | 
						|
      interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
 | 
						|
    else
 | 
						|
      interfaces = new Class[] { mxbeanInterface };
 | 
						|
    return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
 | 
						|
                                      interfaces,
 | 
						|
                                      new ManagementInvocationHandler(connection, bean));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This invocation handler provides method calls for a platform bean
 | 
						|
   * by forwarding them to a {@link MBeanServerConnection}.  Translation from
 | 
						|
   * Java data types to open data types is performed as specified above.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class ManagementInvocationHandler
 | 
						|
    implements InvocationHandler
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * The encapsulated connection.
 | 
						|
     */
 | 
						|
    private MBeanServerConnection conn;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The bean being proxied.
 | 
						|
     */
 | 
						|
    private ObjectName bean;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructs a new {@link InvocationHandler} which proxies
 | 
						|
     * for the specified bean using the supplied connection.
 | 
						|
     *
 | 
						|
     * @param conn the connection on which to forward method calls.
 | 
						|
     * @param bean the bean to proxy.
 | 
						|
     */
 | 
						|
    public ManagementInvocationHandler(MBeanServerConnection conn,
 | 
						|
                                       ObjectName bean)
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      this.conn = conn;
 | 
						|
      this.bean = bean;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called by the proxy class whenever a method is called.  The method
 | 
						|
     * is emulated by retrieving an attribute from, setting an attribute on
 | 
						|
     * or invoking a method on the server connection as required.  Translation
 | 
						|
     * between the Java data types supplied as arguments to the open types used
 | 
						|
     * by the bean is provided, as well as translation of the return value back
 | 
						|
     * in to the appropriate Java type.
 | 
						|
     *
 | 
						|
     * @param proxy the proxy on which the method was called.
 | 
						|
     * @param method the method which was called.
 | 
						|
     * @param args the arguments supplied to the method.
 | 
						|
     * @return the return value from the method.
 | 
						|
     * @throws Throwable if an exception is thrown in performing the
 | 
						|
     *                   method emulation.
 | 
						|
     */
 | 
						|
    public Object invoke(Object proxy, Method method, Object[] args)
 | 
						|
      throws Throwable
 | 
						|
    {
 | 
						|
      String name = method.getName();
 | 
						|
      if (name.equals("toString"))
 | 
						|
        return "Proxy for " + bean + " using " + conn;
 | 
						|
      if (name.equals("addNotificationListener"))
 | 
						|
        {
 | 
						|
          conn.addNotificationListener(bean,
 | 
						|
                                       (NotificationListener) args[0],
 | 
						|
                                       (NotificationFilter) args[1],
 | 
						|
                                       args[2]);
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
      if (name.equals("getNotificationInfo"))
 | 
						|
        return conn.getMBeanInfo(bean).getNotifications();
 | 
						|
      if (name.equals("removeNotificationListener"))
 | 
						|
        {
 | 
						|
          if (args.length == 1)
 | 
						|
            conn.removeNotificationListener(bean,
 | 
						|
                                            (NotificationListener)
 | 
						|
                                            args[0]);
 | 
						|
          else
 | 
						|
            conn.removeNotificationListener(bean,
 | 
						|
                                            (NotificationListener)
 | 
						|
                                            args[0],
 | 
						|
                                            (NotificationFilter)
 | 
						|
                                            args[1], args[2]);
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
      String attrib = null;
 | 
						|
      if (name.startsWith("get"))
 | 
						|
        attrib = name.substring(3);
 | 
						|
      else if (name.startsWith("is"))
 | 
						|
        attrib = name.substring(2);
 | 
						|
      if (attrib != null)
 | 
						|
        return translate(conn.getAttribute(bean, attrib), method);
 | 
						|
      else if (name.startsWith("set"))
 | 
						|
        {
 | 
						|
          conn.setAttribute(bean, new Attribute(name.substring(3),
 | 
						|
                                                args[0]));
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
      else
 | 
						|
        return translate(conn.invoke(bean, name, args, null), method);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Translates the returned open data type to the value
 | 
						|
     * required by the interface.
 | 
						|
     *
 | 
						|
     * @param otype the open type returned by the method call.
 | 
						|
     * @param method the method that was called.
 | 
						|
     * @return the equivalent return type required by the interface.
 | 
						|
     * @throws Throwable if an exception is thrown in performing the
 | 
						|
     *                   conversion.
 | 
						|
     */
 | 
						|
    private final Object translate(Object otype, Method method)
 | 
						|
      throws Throwable
 | 
						|
    {
 | 
						|
      Class<?> returnType = method.getReturnType();
 | 
						|
      if (returnType.isEnum())
 | 
						|
        {
 | 
						|
          String ename = (String) otype;
 | 
						|
          Enum[] constants = (Enum[]) returnType.getEnumConstants();
 | 
						|
          for (Enum c : constants)
 | 
						|
            if (c.name().equals(ename))
 | 
						|
              return c;
 | 
						|
        }
 | 
						|
      if (List.class.isAssignableFrom(returnType))
 | 
						|
        {
 | 
						|
          Object[] elems = (Object[]) otype;
 | 
						|
          List l = new ArrayList(elems.length);
 | 
						|
          for (Object elem : elems)
 | 
						|
            l.add(elem);
 | 
						|
          return l;
 | 
						|
        }
 | 
						|
      if (Map.class.isAssignableFrom(returnType))
 | 
						|
        {
 | 
						|
          TabularData data = (TabularData) otype;
 | 
						|
          Map m = new HashMap(data.size());
 | 
						|
          for (Object val : data.values())
 | 
						|
            {
 | 
						|
              CompositeData vals = (CompositeData) val;
 | 
						|
              m.put(vals.get("key"), vals.get("value"));
 | 
						|
            }
 | 
						|
          return m;
 | 
						|
        }
 | 
						|
      try
 | 
						|
        {
 | 
						|
          Method m = returnType.getMethod("from",
 | 
						|
                                          new Class[]
 | 
						|
            { CompositeData.class });
 | 
						|
          return m.invoke(null, (CompositeData) otype);
 | 
						|
        }
 | 
						|
      catch (NoSuchMethodException e)
 | 
						|
        {
 | 
						|
          /* Ignored; we expect this if this
 | 
						|
             isn't a from(CompositeData) class */
 | 
						|
        }
 | 
						|
      return otype;
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
}
 |