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++) {