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

ClassLoaderRepositorySupport

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.
since
1.5
since.unbundled
JMX RI 1.2

Fields Summary
private static final LoaderEntry[]
EMPTY_LOADER_ARRAY
private LoaderEntry[]
loaders
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
search
List of valid search
private final Map
loadersWithNames
List of named class loaders.
private static final String
dbgTag
Constructors Summary
Methods Summary
private synchronized booleanadd(javax.management.ObjectName 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(javax.management.ObjectName 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(javax.management.ObjectName 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 javax.management.loading.DefaultLoaderRepository
        
	  
	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)
		    continue;
		if (cl == stop)
		    break;
		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(javax.management.ObjectName 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 :
		name.equals(entry.name);
	    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(javax.management.ObjectName 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);
        }
        excluded.add(aloader);
	if (isTraceOn()) {
	    trace("startValidSearch", "loader=" + aloader + " class= " +
		  className);
	}
    
private synchronized voidstopValidSearch(java.lang.ClassLoader aloader, java.lang.String className)


        // Retrieve the search.
        //
        List<ClassLoader> excluded = search.get(className);
        if (excluded != null) {
            excluded.remove(aloader);
	    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);