Index: ProxyClassLoader.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/modules/ProxyClassLoader.java,v retrieving revision 1.6 diff -u -r1.6 ProxyClassLoader.java --- ProxyClassLoader.java 8 Oct 2001 14:37:21 -0000 1.6 +++ ProxyClassLoader.java 11 Feb 2002 10:15:55 -0000 @@ -16,6 +16,7 @@ import java.util.*; import java.net.URL; import java.io.IOException; +import org.openide.*; import org.openide.util.WeakSet; import org.openide.util.enum.RemoveDuplicatesEnumeration; import org.openide.util.enum.SequenceEnumeration; @@ -32,11 +33,6 @@ */ public class ProxyClassLoader extends ClassLoader { - /** Set<ProxyClassLoader> of all live instancef of all - * ProxyClassLoaders, usefull when we need to destroy a ProxyClassLoader - * that is in other ProxyClassLoader's list of parents. - */ - private static final Set instances = new WeakSet(); // Map private final Map domainsByPackage = new HashMap(); // Map @@ -45,6 +41,8 @@ // All parentf of this classloader, including their parents recursively private ClassLoader[] parents; + /** if true, we have been destroyed */ + private boolean dead = false; /** Create a multi-parented classloader. * @param parents list of parent classloaders. @@ -61,10 +59,6 @@ if (check.contains(null)) throw new IllegalArgumentException("null parent"); // NOI18N this.parents = coalesceParents(parents); - - synchronized (instances) { - instances.add(this); - } } // this is used only by system classloader, maybe we can redesign it a bit @@ -85,31 +79,19 @@ - // Is this needed? Before this classloader can go bye-bey, every childer - // of it should be bye-bye too? Except SystemClassLoader /** Try to destroy this classloader. - * It will be removed from the parent lists of all existing ProxyClassLoaders. + * Subsequent attempts to use it will log an error (at most one though). */ public void destroy() { - synchronized (instances) { - Iterator it = instances.iterator(); - while (it.hasNext()) { - ProxyClassLoader pcl = (ProxyClassLoader)it.next(); - synchronized (pcl) { - ClassLoader[] p = pcl.parents; - for (int i = 0; i < p.length; i++) { - if (p[i] == this) { - ClassLoader[] p2 = new ClassLoader[p.length - 1]; - if (i > 0) System.arraycopy(p, 0, p2, 0, i); - if (i < p.length - 1) System.arraycopy(p, i + 1, p2, i, p.length - i - 1); - pcl.parents = p2; - break; - } - } - Collection c = pcl.domainsByPackage.values(); - while (c.remove(this)) ; - } - } + dead = true; + } + + private void zombieCheck(String hint) { + if (dead) { + IllegalStateException ise = new IllegalStateException("Attempting to use a zombie classloader " + this + " on " + hint); // NOI18N + TopManager.getDefault().getErrorManager().notify(ErrorManager.INFORMATIONAL, ise); + // don't warn again for same loader... this was enough + dead = false; } } @@ -133,6 +115,7 @@ */ protected synchronized final Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + zombieCheck(name); final int dotIdx = name.lastIndexOf('.'); if (dotIdx == -1) throw new ClassNotFoundException("Will not load classes from default package"); // NOI18N Class c = smartLoadClass(name, dotIdx); @@ -175,6 +158,8 @@ * @see #findResource(String) */ public final URL getResource(final String name) { + zombieCheck(name); + final int slashIdx = name.lastIndexOf('/'); if (slashIdx == -1) return null; // won't load from the default package final String pkg = name.substring(0, slashIdx); @@ -235,6 +220,7 @@ * @throws IOException if I/O errors occur */ protected final synchronized Enumeration findResources(String name) throws IOException { + zombieCheck(name); // Don't bother optimizing this call by domains--it is practically unused. Enumeration e = simpleFindResources(name); for (int i = parents.length - 1; i >= 0; i--) { @@ -265,6 +251,7 @@ * @return the Package corresponding to the given name, or null if not found */ protected Package getPackage(String name) { + zombieCheck(name); synchronized (packages) { Package pkg = (Package)packages.get(name); if (pkg != null) return pkg; @@ -305,6 +292,7 @@ * ClassLoader */ protected synchronized Package[] getPackages() { + zombieCheck(null); Map all = new HashMap(); // Map addPackages(all, super.getPackages()); for (int i = 0; i < parents.length; i++) {