718 lines · 26.9 KB · Java
RawDownload
/* * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.jmx.mbeanserver;  import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;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.Map;import java.util.logging.Level; import javax.management.InstanceNotFoundException;import javax.management.MBeanException;import javax.management.NotCompliantMBeanException;import javax.management.ObjectName;import javax.management.OperationsException;import javax.management.ReflectionException;import javax.management.RuntimeErrorException;import javax.management.RuntimeMBeanException;import javax.management.RuntimeOperationsException; import sun.reflect.misc.ReflectUtil; /** * Implements the MBeanInstantiator interface. Provides methods for * instantiating objects, finding the class given its name and using * different class loaders, deserializing objects in the context of a * given class loader. * * @since 1.5 */public class MBeanInstantiator {     private final ModifiableClassLoaderRepository clr;    //    private MetaData meta = null;     MBeanInstantiator(ModifiableClassLoaderRepository clr) {        this.clr = clr;    }      /**     * This methods tests if the MBean class makes it possible to     * instantiate an MBean of this class in the MBeanServer.     * e.g. it must have a public constructor, be a concrete class...     */    public void testCreation(Class<?> c) throws NotCompliantMBeanException {        Introspector.testCreation(c);    }     /**     * Loads the class with the specified name using this object's     * Default Loader Repository.     **/    public Class<?> findClassWithDefaultLoaderRepository(String className)        throws ReflectionException {         Class<?> theClass;        if (className == null) {            throw new RuntimeOperationsException(new                IllegalArgumentException("The class name cannot be null"),                             "Exception occurred during object instantiation");        }         try {            if (clr == null) throw new ClassNotFoundException(className);            theClass = clr.loadClass(className);        }        catch (ClassNotFoundException ee) {            throw new ReflectionException(ee,       "The MBean class could not be loaded by the default loader repository");        }         return theClass;    }      /**     * Gets the class for the specified class name using the MBean     * Interceptor's classloader     */    public Class<?> findClass(String className, ClassLoader loader)        throws ReflectionException {         return loadClass(className,loader);    }     /**     * Gets the class for the specified class name using the specified     * class loader     */    public Class<?> findClass(String className, ObjectName aLoader)        throws ReflectionException, InstanceNotFoundException  {         if (aLoader == null)            throw new RuntimeOperationsException(new                IllegalArgumentException(), "Null loader passed in parameter");         // Retrieve the class loader from the repository        ClassLoader loader = null;        synchronized(this) {            if (clr!=null)                loader = clr.getClassLoader(aLoader);        }        if (loader == null) {            throw new InstanceNotFoundException("The loader named " +                       aLoader + " is not registered in the MBeanServer");        }        return findClass(className,loader);    }      /**     * Return an array of Class corresponding to the given signature, using     * the specified class loader.     */    public Class<?>[] findSignatureClasses(String signature[],                                           ClassLoader loader)        throws ReflectionException {         if (signature == null) return null;        final ClassLoader aLoader = loader;        final int length= signature.length;        final Class<?> tab[]=new Class<?>[length];         if (length == 0) return tab;        try {            for (int i= 0; i < length; i++) {                // Start handling primitive types (int. boolean and so                // forth)                //                 final Class<?> primCla = primitiveClasses.get(signature[i]);                if (primCla != null) {                    tab[i] = primCla;                    continue;                }                 // Ok we do not have a primitive type ! We need to build                // the signature of the method                //                if (aLoader != null) {                    // We need to load the class through the class                    // loader of the target object.                    //                    tab[i] = Class.forName(signature[i], false, aLoader);                } else {                    // Load through the default class loader                    //                    tab[i] = findClass(signature[i],                                       this.getClass().getClassLoader());                }            }        } catch (ClassNotFoundException e) {            if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {                MBEANSERVER_LOGGER.logp(Level.FINEST,                        MBeanInstantiator.class.getName(),                        "findSignatureClasses",                        "The parameter class could not be found", e);            }            throw new ReflectionException(e,                      "The parameter class could not be found");        } catch (RuntimeException e) {            if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {                MBEANSERVER_LOGGER.logp(Level.FINEST,                        MBeanInstantiator.class.getName(),                        "findSignatureClasses",                        "Unexpected exception", e);            }            throw e;        }        return tab;    }      /**     * Instantiates an object given its class, using its empty constructor.     * The call returns a reference to the newly created object.     */    public Object instantiate(Class<?> theClass)        throws ReflectionException, MBeanException {        Object moi;          // ------------------------------        // ------------------------------        Constructor<?> cons = findConstructor(theClass, null);        if (cons == null) {            throw new ReflectionException(new                NoSuchMethodException("No such constructor"));        }        // Instantiate the new object        try {            ReflectUtil.checkPackageAccess(theClass);            moi= cons.newInstance();        } catch (InvocationTargetException e) {            // Wrap the exception.            Throwable t = e.getTargetException();            if (t instanceof RuntimeException) {                throw new RuntimeMBeanException((RuntimeException)t,                   "RuntimeException thrown in the MBean's empty constructor");            } else if (t instanceof Error) {                throw new RuntimeErrorException((Error) t,                   "Error thrown in the MBean's empty constructor");            } else {                throw new MBeanException((Exception) t,                   "Exception thrown in the MBean's empty constructor");            }        } catch (NoSuchMethodError error) {            throw new ReflectionException(new                NoSuchMethodException("No constructor"),                                          "No such constructor");        } catch (InstantiationException e) {            throw new ReflectionException(e,            "Exception thrown trying to invoke the MBean's empty constructor");        } catch (IllegalAccessException e) {            throw new ReflectionException(e,            "Exception thrown trying to invoke the MBean's empty constructor");        } catch (IllegalArgumentException e) {            throw new ReflectionException(e,            "Exception thrown trying to invoke the MBean's empty constructor");        }        return moi;     }      /**     * Instantiates an object given its class, the parameters and     * signature of its constructor The call returns a reference to     * the newly created object.     */    public Object instantiate(Class<?> theClass, Object params[],                              String signature[], ClassLoader loader)        throws ReflectionException, MBeanException {        // Instantiate the new object         // ------------------------------        // ------------------------------        final Class<?>[] tab;        Object moi;        try {            // Build the signature of the method            //            ClassLoader aLoader= theClass.getClassLoader();            // Build the signature of the method            //            tab =                ((signature == null)?null:                 findSignatureClasses(signature,aLoader));        }        // Exception IllegalArgumentException raised in Jdk1.1.8        catch (IllegalArgumentException e) {            throw new ReflectionException(e,                    "The constructor parameter classes could not be loaded");        }         // Query the metadata service to get the right constructor        Constructor<?> cons = findConstructor(theClass, tab);         if (cons == null) {            throw new ReflectionException(new                NoSuchMethodException("No such constructor"));        }        try {            ReflectUtil.checkPackageAccess(theClass);            moi = cons.newInstance(params);        }        catch (NoSuchMethodError error) {            throw new ReflectionException(new                NoSuchMethodException("No such constructor found"),                                          "No such constructor" );        }        catch (InstantiationException e) {            throw new ReflectionException(e,                "Exception thrown trying to invoke the MBean's constructor");        }        catch (IllegalAccessException e) {            throw new ReflectionException(e,                "Exception thrown trying to invoke the MBean's constructor");        }        catch (InvocationTargetException e) {            // Wrap the exception.            Throwable th = e.getTargetException();            if (th instanceof RuntimeException) {                throw new RuntimeMBeanException((RuntimeException)th,                      "RuntimeException thrown in the MBean's constructor");            } else if (th instanceof Error) {                throw new RuntimeErrorException((Error) th,                      "Error thrown in the MBean's constructor");            } else {                throw new MBeanException((Exception) th,                      "Exception thrown in the MBean's constructor");            }        }        return moi;    }     /**     * De-serializes a byte array in the context of a classloader.     *     * @param loader the classloader to use for de-serialization     * @param data The byte array to be de-sererialized.     *     * @return  The de-serialized object stream.     *     * @exception OperationsException Any of the usual Input/Output related     * exceptions.     */    public ObjectInputStream deserialize(ClassLoader loader, byte[] data)        throws OperationsException {         // Check parameter validity        if (data == null) {            throw new  RuntimeOperationsException(new                IllegalArgumentException(), "Null data passed in parameter");        }        if (data.length == 0) {            throw new  RuntimeOperationsException(new                IllegalArgumentException(), "Empty data passed in parameter");        }         // Object deserialization        ByteArrayInputStream bIn;        ObjectInputStream    objIn;         bIn   = new ByteArrayInputStream(data);        try {            objIn = new ObjectInputStreamWithLoader(bIn,loader);        } catch (IOException e) {            throw new OperationsException(                     "An IOException occurred trying to de-serialize the data");        }         return objIn;    }     /**     * De-serializes a byte array in the context of a given MBean class loader.     * <P>The class loader is the one that loaded the class with name     * "className".     * <P>The name of the class loader to be used for loading the specified     * class is specified. If null, a default one has to be provided (for a     * MBean Server, its own class loader will be used).     *     * @param className The name of the class whose class loader should     *  be used for the de-serialization.     * @param data The byte array to be de-sererialized.     * @param loaderName The name of the class loader to be used for loading     * the specified class. If null, a default one has to be provided (for a     * MBean Server, its own class loader will be used).     *     * @return  The de-serialized object stream.     *     * @exception InstanceNotFoundException The specified class loader MBean is     * not found.     * @exception OperationsException Any of the usual Input/Output related     * exceptions.     * @exception ReflectionException The specified class could not be loaded     * by the specified class loader.     */    public ObjectInputStream deserialize(String className,                                         ObjectName loaderName,                                         byte[] data,                                         ClassLoader loader)        throws InstanceNotFoundException,               OperationsException,               ReflectionException  {         // Check parameter validity        if (data == null) {            throw new  RuntimeOperationsException(new                IllegalArgumentException(), "Null data passed in parameter");        }        if (data.length == 0) {            throw new  RuntimeOperationsException(new                IllegalArgumentException(), "Empty data passed in parameter");        }        if (className == null) {            throw new  RuntimeOperationsException(new             IllegalArgumentException(), "Null className passed in parameter");        }        Class<?> theClass;        if (loaderName == null) {            // Load the class using the agent class loader            theClass = findClass(className, loader);         } else {            // Get the class loader MBean            try {                ClassLoader instance = null;                 if (clr!=null)                    instance = clr.getClassLoader(loaderName);                if (instance == null)                    throw new ClassNotFoundException(className);                theClass = Class.forName(className, false, instance);            }            catch (ClassNotFoundException e) {                throw new ReflectionException(e,                               "The MBean class could not be loaded by the " +                               loaderName.toString() + " class loader");            }        }         // Object deserialization        ByteArrayInputStream bIn;        ObjectInputStream    objIn;         bIn   = new ByteArrayInputStream(data);        try {            objIn = new ObjectInputStreamWithLoader(bIn,                                           theClass.getClassLoader());        } catch (IOException e) {            throw new OperationsException(                    "An IOException occurred trying to de-serialize the data");        }         return objIn;    }      /**     * Instantiates an object using the list of all class loaders registered     * in the MBean Interceptor     * (using its {@link javax.management.loading.ClassLoaderRepository}).     * <P>The object's class should have a public constructor.     * <P>It returns a reference to the newly created object.     * <P>The newly created object is not registered in the MBean Interceptor.     *     * @param className The class name of the object to be instantiated.     *     * @return The newly instantiated object.     *     * @exception ReflectionException Wraps a     * <CODE>java.lang.ClassNotFoundException</CODE> or the     * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the     * object's constructor.     * @exception MBeanException The constructor of the object has thrown an     * exception     * @exception RuntimeOperationsException Wraps a     * <CODE>java.lang.IllegalArgumentException</CODE>: the className passed in     * parameter is null.     */    public Object instantiate(String className)        throws ReflectionException,        MBeanException {         return instantiate(className, (Object[]) null, (String[]) null, null);    }       /**     * Instantiates an object using the class Loader specified by its     * <CODE>ObjectName</CODE>.     * <P>If the loader name is null, a default one has to be provided (for a     * MBean Server, the ClassLoader that loaded it will be used).     * <P>The object's class should have a public constructor.     * <P>It returns a reference to the newly created object.     * <P>The newly created object is not registered in the MBean Interceptor.     *     * @param className The class name of the MBean to be instantiated.     * @param loaderName The object name of the class loader to be used.     *     * @return The newly instantiated object.     *     * @exception ReflectionException Wraps a     * <CODE>java.lang.ClassNotFoundException</CODE> or the     * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the     * object's constructor.     * @exception MBeanException The constructor of the object has thrown an     * exception.

Lines 1–500 of 718.