/*
* @(#)MBeanInstantiatorImpl.java 1.31 05/05/27
*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.jmx.mbeanserver;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.io.*;
import javax.management.*;
import javax.management.loading.ClassLoaderRepository;
import com.sun.jmx.trace.Trace;
/**
* 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
* @since.unbundled JMX RI 1.2
*/
class MBeanInstantiatorImpl implements MBeanInstantiator {
private final ModifiableClassLoaderRepository clr;
// private MetaData meta = null;
/** The name of this class to be used for tracing */
private final static String dbgTag = "MBeanInstantiatorImpl";
public MBeanInstantiatorImpl(ModifiableClassLoaderRepository clr) {
this.clr = clr;
}
public void testCreation(Class c) throws NotCompliantMBeanException {
Introspector.testCreation(c);
}
public Class findClassWithDefaultLoaderRepository(String className)
throws ReflectionException {
Class theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
"Exception occured 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;
}
public Class findClass(String className, ClassLoader loader)
throws ReflectionException {
return loadClass(className,loader);
}
public Class findClass(String className, ObjectName aLoader)
throws ReflectionException, InstanceNotFoundException {
Class theClass = null;
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);
}
public Class[] findSignatureClasses(String signature[],
ClassLoader loader)
throws ReflectionException {
if (signature == null) return null;
final ClassLoader aLoader = (ClassLoader) 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 =
StandardMetaDataImpl.findClassForPrim(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) {
debugX("findSignatureClasses",e);
throw new ReflectionException(e,
"The parameter class could not be found");
} catch (RuntimeException e) {
debugX("findSignatureClasses",e);
throw e;
}
return tab;
}
public Object instantiate(Class theClass)
throws ReflectionException, MBeanException {
Object moi = null;
// ------------------------------
// ------------------------------
Constructor cons =
StandardMetaDataImpl.findConstructor(theClass, null);
if (cons == null) {
throw new ReflectionException(new
NoSuchMethodException("No such constructor"));
}
// Instantiate the new object
try {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(theClass.getName());
}
moi= cons.newInstance((Object[]) null);
} 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;
}
public Object instantiate(Class theClass, Object params[],
String signature[], ClassLoader loader)
throws ReflectionException, MBeanException {
// Instantiate the new object
// ------------------------------
// ------------------------------
final Class[] tab;
Object moi= null;
try {
// Build the signature of the method
//
ClassLoader aLoader= (ClassLoader) 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 = null;
cons= StandardMetaDataImpl.findConstructor(theClass, tab);
if (cons == null) {
throw new ReflectionException(new
NoSuchMethodException("No such constructor"));
}
try {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(theClass.getName());
}
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;
}
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;
String typeStr;
bIn = new ByteArrayInputStream(data);
try {
objIn = new ObjectInputStreamWithLoader(bIn,loader);
} catch (IOException e) {
throw new OperationsException(
"An IOException occured trying to de-serialize the data");
}
return objIn;
}
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 = null;
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;
String typeStr;
bIn = new ByteArrayInputStream(data);
try {
objIn = new ObjectInputStreamWithLoader(bIn,
theClass.getClassLoader());
} catch (IOException e) {
throw new OperationsException(
"An IOException occured trying to de-serialize the data");
}
return objIn;
}
public Object instantiate(String className)
throws ReflectionException,
MBeanException {
return instantiate(className, (Object[]) null, (String[]) null, null);
}
public Object instantiate(String className, ObjectName loaderName,
ClassLoader loader)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
return instantiate(className, loaderName, (Object[]) null,
(String[]) null, loader);
}
public Object instantiate(String className,
Object params[],
String signature[],
ClassLoader loader)
throws ReflectionException,
MBeanException {
Class theClass = findClassWithDefaultLoaderRepository(className);
return instantiate(theClass, params, signature, loader);
}
public Object instantiate(String className,
ObjectName loaderName,
Object params[],
String signature[],
ClassLoader loader)
throws ReflectionException,
MBeanException,
InstanceNotFoundException {
// ------------------------------
// ------------------------------
Class theClass;
if (loaderName == null) {
theClass = findClass(className, loader);
} else {
theClass = findClass(className, loaderName);
}
return instantiate(theClass, params, signature, loader);
}
public ModifiableClassLoaderRepository getClassLoaderRepository() {
return clr;
}
/**
* Load a class with the specified loader, or with this object
* class loader if the specified loader is null.
**/
static Class loadClass(String className, ClassLoader loader)
throws ReflectionException {
Class theClass = null;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
"Exception occured during object instantiation");
}
try {
if (loader == null)
loader = MBeanInstantiatorImpl.class.getClassLoader();
if (loader != null) {
theClass = Class.forName(className, false, loader);
} else {
theClass = Class.forName(className);
}
} catch (ClassNotFoundException e) {
throw new ReflectionException(e,
"The MBean class could not be loaded by the context classloader");
}
return theClass;
}
/**
* Load the classes specified in the signature with the given loader,
* or with this object class loader.
**/
static Class[] loadSignatureClasses(String signature[],
ClassLoader loader)
throws ReflectionException {
if (signature == null) return null;
final ClassLoader aLoader =
(loader==null?MBeanInstantiatorImpl.class.getClassLoader():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 =
StandardMetaDataImpl.findClassForPrim(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
//
// We need to load the class through the class
// loader of the target object.
//
tab[i] = Class.forName(signature[i], false, aLoader);
}
} catch (ClassNotFoundException e) {
debugX("findSignatureClasses",e);
throw new ReflectionException(e,
"The parameter class could not be found");
} catch (RuntimeException e) {
debugX("findSignatureClasses",e);
throw e;
}
return tab;
}
// TRACES & DEBUG
//---------------
private static boolean isTraceOn() {
return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER);
}
private static void trace(String clz, String func, String info) {
Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER, clz, func, info);
}
private static void trace(String func, String info) {
trace(dbgTag, func, info);
}
private static boolean isDebugOn() {
return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER);
}
private static void debug(String clz, String func, String info) {
Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER, clz, func, info);
}
private static void debug(String func, String info) {
debug(dbgTag, func, info);
}
private static void debugX(String func,Throwable e) {
if (isDebugOn()) {
final StringWriter s = new StringWriter();
e.printStackTrace(new PrintWriter(s));
final String stack = s.toString();
debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
debug(dbgTag,func,stack);
// java.lang.System.err.println("**** Exception caught in "+
// func+"(): "+e);
// java.lang.System.err.println(stack);
}
}
}
|