ClassLoaderRepositorySupport.javaAPI DocJava SE 6 API9379Tue Jun 10 00:22:02 BST 2008com.sun.jmx.mbeanserver


public final class ClassLoaderRepositorySupport extends Object implements ModifiableClassLoaderRepository
This class keeps the list of Class Loaders registered in the MBean Server. It provides the necessary methods to load classes using the registered Class Loaders.
JMX RI 1.2

Fields Summary
private static final LoaderEntry[]
private LoaderEntry[]
List of class loaders Only read-only actions should be performed on this object. We do O(n) operations on this array, e.g. when removing a ClassLoader. The assumption is that the number of elements is small, probably less than ten, and that the vast majority of operations are searches (loadClass) which are by definition linear.
private final Map
List of valid search
private final Map
List of named class loaders.
private static final String
Constructors Summary
Methods Summary
private synchronized booleanadd( name, java.lang.ClassLoader cl)
Same behavior as add(Object o) in {@link java.util.List}. Replace the loader list with a new one in which the new loader has been added.

	List<LoaderEntry> l =
	    new ArrayList<LoaderEntry>(Arrays.asList(loaders));
	l.add(new LoaderEntry(name, cl));
	loaders = l.toArray(EMPTY_LOADER_ARRAY);
	return true;
public final synchronized voidaddClassLoader( name, java.lang.ClassLoader loader)

	loadersWithNames.put(name, loader);
	if (!(loader instanceof PrivateClassLoader))
	    add(name, loader);
public final voidaddClassLoader(java.lang.ClassLoader loader)

	add(null, loader);
private static voiddebug(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER,clz,func,info);
private static voiddebug(java.lang.String func, java.lang.String info)

        debug(dbgTag, func, info);
public final java.lang.ClassLoadergetClassLoader( name)

	return loadersWithNames.get(name);
private static booleanisDebugOn()

        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER);
private static booleanisTraceOn()

        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER);
public final java.lang.ClassloadClass(java.lang.String className)

    // from
	return  loadClass(loaders, className, null, null);
private java.lang.ClassloadClass(com.sun.jmx.mbeanserver.ClassLoaderRepositorySupport$LoaderEntry[] list, java.lang.String className, java.lang.ClassLoader without, java.lang.ClassLoader stop)

	final int size = list.length;
        for(int i=0; i<size; i++) {
	    try {
		final ClassLoader cl = list[i].loader;
		if (cl == null) // bootstrap class loader
		    return Class.forName(className, false, null);
		if (cl == without)
		if (cl == stop)
		if (isTraceOn()) {
		    trace("loadClass", "trying loader = " + cl);
		/* We used to have a special case for "instanceof
		   MLet" here, where we invoked the method
		   loadClass(className, null) to prevent infinite
		   recursion.  But the rule whereby the MLet only
		   consults loaders that precede it in the CLR (via
		   loadClassBefore) means that the recursion can't
		   happen, and the test here caused some legitimate
		   classloading to fail.  For example, if you have
		   dependencies C->D->E with loaders {E D C} in the
		   CLR in that order, you would expect to be able to
		   load C.  The problem is that while resolving D, CLR
		   delegation is disabled, so it can't find E.  */
		return Class.forName(className, false, cl);
            } catch (ClassNotFoundException e) {
		// OK: continue with next class

        throw new ClassNotFoundException(className);
public final java.lang.ClassloadClassBefore(java.lang.ClassLoader stop, java.lang.String className)

	if (isTraceOn())
	    trace("loadClassBefore", className + "\tbefore " + stop);

	if (stop == null)
	    return loadClass(loaders, className, null, null);

	startValidSearch(stop, className);
	try {
	    return loadClass(loaders, className, null, stop);
	} finally {
	    stopValidSearch(stop, className);
public final java.lang.ClassloadClassWithout(java.lang.ClassLoader without, java.lang.String className)

	if (isTraceOn()) {
	    trace("loadClassWithout", className + "\twithout " + without);

	// without is null => just behave as loadClass
	if (without == null)
	    return loadClass(loaders, className, null, null);

	// We must try to load the class without the given loader.
	startValidSearch(without, className);
	try {
	    return loadClass(loaders, className, without, null);
	} finally {
	    stopValidSearch(without, className);
private synchronized booleanremove( name, java.lang.ClassLoader cl)
Same behavior as remove(Object o) in {@link java.util.List}. Replace the loader list with a new one in which the old loader has been removed. The ObjectName may be null, in which case the entry to be removed must also have a null ObjectName and the ClassLoader values must match. If the ObjectName is not null, then the first entry with a matching ObjectName is removed, regardless of whether ClassLoader values match. (In fact, the ClassLoader parameter will usually be null in this case.)

	final int size = loaders.length;
	for (int i = 0; i < size; i++) {
	    LoaderEntry entry = loaders[i];
	    boolean match =
		(name == null) ?
		cl == entry.loader :
	    if (match) {
		LoaderEntry[] newloaders = new LoaderEntry[size - 1];
		System.arraycopy(loaders, 0, newloaders, 0, i);
		System.arraycopy(loaders, i + 1, newloaders, i,
				 size - 1 - i);
		loaders = newloaders;
		return true;
	return false;
public final voidremoveClassLoader(java.lang.ClassLoader loader)

	remove(null, loader);
public final synchronized voidremoveClassLoader( name)

	ClassLoader loader = loadersWithNames.remove(name);
	if (!(loader instanceof PrivateClassLoader))
	    remove(name, loader);
private synchronized voidstartValidSearch(java.lang.ClassLoader aloader, java.lang.String className)

        // Check if we have such a current search
        List<ClassLoader> excluded = search.get(className);
        if ((excluded!= null) && (excluded.contains(aloader))) {
	    if (isTraceOn()) {
		trace("startValidSearch", "already requested loader=" +
		      aloader + " class= " + className);
            throw new ClassNotFoundException(className);

        // Add an entry
        if (excluded == null) {
            excluded = new ArrayList<ClassLoader>(1);
            search.put(className, excluded);
	if (isTraceOn()) {
	    trace("startValidSearch", "loader=" + aloader + " class= " +
private synchronized voidstopValidSearch(java.lang.ClassLoader aloader, java.lang.String className)

        // Retrieve the search.
        List<ClassLoader> excluded = search.get(className);
        if (excluded != null) {
	    if (isTraceOn()) {
		trace("stopValidSearch", "loader=" + aloader +
		      " class= " + className);
private static voidtrace(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER,clz,func,info);
private static voidtrace(java.lang.String func, java.lang.String info)

        trace(dbgTag, func, info);