]> source.dussan.org Git - aspectj.git/commitdiff
210470: preventing weaver leaks: get control of the classloader references in Bcel
authoraclement <aclement>
Tue, 27 May 2008 18:46:34 +0000 (18:46 +0000)
committeraclement <aclement>
Tue, 27 May 2008 18:46:34 +0000 (18:46 +0000)
bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java [new file with mode: 0644]
bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java
bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java [new file with mode: 0644]
bcel-builder/src/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java

diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderReference.java
new file mode 100644 (file)
index 0000000..f6fcbf5
--- /dev/null
@@ -0,0 +1,67 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache BCEL" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache BCEL", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.aspectj.apache.bcel.util;
+
+/**
+ * Implementors should provide access to a ClassLoader instance.  The reference can be passed around and cached
+ * but will not cause the code that caches it to have a hard reference to the classloader, so it is easier
+ * to manage the classloader instance.  The default implementation will just wrap a classloader object but
+ * more sophisticated implementations could keep a WeakReference to the loader.
+ */
+public interface ClassLoaderReference {
+
+    java.lang.ClassLoader getClassLoader();
+    
+}
index f7cdee26b1c9645caa728d6e1d3756a19f575040..74f3d47a24a757fc3cbecb6ecdf219732212e513 100644 (file)
@@ -80,13 +80,13 @@ import org.aspectj.apache.bcel.classfile.JavaClass;
  *
  * @see org.aspectj.apache.bcel.Repository
  *
- * @version $Id: ClassLoaderRepository.java,v 1.9 2006/10/12 19:58:18 aclement Exp $
+ * @version $Id: ClassLoaderRepository.java,v 1.10 2008/05/27 18:46:34 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @author David Dixon-Peugh
  */
 public class ClassLoaderRepository implements Repository {
   private static java.lang.ClassLoader bootClassLoader = null;
-  private java.lang.ClassLoader loader;
+  private ClassLoaderReference loaderRef;
   
   // Choice of cache...
   private         WeakHashMap /*<URL,SoftRef(JavaClass)>*/localCache = new WeakHashMap(); 
@@ -107,9 +107,13 @@ public class ClassLoaderRepository implements Repository {
   private int  cacheHitsLocal     = 0;
   private int  missLocalEvicted   = 0; // Misses in local cache access due to reference GC
 
-  public ClassLoaderRepository( java.lang.ClassLoader loader ) {
-      this.loader = (loader != null) ? loader : getBootClassLoader();
-  }
+    public ClassLoaderRepository(java.lang.ClassLoader loader) {
+        this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader());
+    }
+
+    public ClassLoaderRepository(ClassLoaderReference loaderRef) {
+        this.loaderRef = loaderRef;
+    }
   
   private static synchronized java.lang.ClassLoader getBootClassLoader() {
          if (bootClassLoader == null) {
@@ -246,7 +250,7 @@ public class ClassLoaderRepository implements Repository {
          URL url = (URL)nameMap.get(className);
          if (url==null) {
                  String classFile = className.replace('.', '/');
-             url = loader.getResource( classFile + ".class" );
+             url = loaderRef.getClassLoader().getResource(classFile + ".class");
              nameMap.put(className, url);
          }
       return url;
@@ -280,7 +284,7 @@ public class ClassLoaderRepository implements Repository {
     try {      
        // Load it
            String classFile = className.replace('.', '/');
-               InputStream is = (useSharedCache?url.openStream():loader.getResourceAsStream( classFile + ".class" ));
+               InputStream is = (useSharedCache ? url.openStream() : loaderRef.getClassLoader().getResourceAsStream(classFile + ".class"));
            if (is == null) { 
                  throw new ClassNotFoundException(className + " not found "+(url==null?"":"- using url "+url));
            }
@@ -298,10 +302,9 @@ public class ClassLoaderRepository implements Repository {
     }
   }
   
-
   /**
-   * Produce a report on cache usage.
-   */
+     * Produce a report on cache usage.
+     */
   public String report() {
          StringBuffer sb = new StringBuffer();
          sb.append("BCEL repository report.");
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java b/bcel-builder/src/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java
new file mode 100644 (file)
index 0000000..2599913
--- /dev/null
@@ -0,0 +1,75 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache BCEL" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache BCEL", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.aspectj.apache.bcel.util;
+
+/**
+ * Simplistic ClassLoaderReference that merely delegates to a classloader. More sophisticated ones could allow for the
+ * loader to be weakly referenced.
+ * 
+ * @author Andy Clement
+ */
+public class DefaultClassLoaderReference implements ClassLoaderReference {
+
+    private java.lang.ClassLoader loader;
+    public DefaultClassLoaderReference(java.lang.ClassLoader classLoader) {
+        this.loader = classLoader;
+    }
+
+    public java.lang.ClassLoader getClassLoader() {
+        return loader;
+    }
+
+}
index 20c82006ddac6cc3759012dc977f9f7874581bd8..d41188cf1180a3c834d19aff0852c0130c9ae257 100644 (file)
@@ -72,7 +72,7 @@ import org.aspectj.apache.bcel.classfile.JavaClass;
  *
  * @see org.aspectj.apache.bcel.Repository
  *
- * @version $Id: NonCachingClassLoaderRepository.java,v 1.1 2006/10/12 19:58:18 aclement Exp $
+ * @version $Id: NonCachingClassLoaderRepository.java,v 1.2 2008/05/27 18:46:34 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @author David Dixon-Peugh
  * 
@@ -82,13 +82,17 @@ public class NonCachingClassLoaderRepository
 {  
   private static java.lang.ClassLoader bootClassLoader = null;
 
-  private java.lang.ClassLoader loader;
+  private ClassLoaderReference loaderRef;
   private WeakHashMap loadedClasses =
     new WeakHashMap(); // CLASSNAME X JAVACLASS
 
-  public NonCachingClassLoaderRepository( java.lang.ClassLoader loader ) {
-           this.loader = (loader != null) ? loader : getBootClassLoader();
-  }
+    public NonCachingClassLoaderRepository(java.lang.ClassLoader loader) {
+        this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader());
+    }
+
+    public NonCachingClassLoaderRepository(ClassLoaderReference loaderRef) {
+        this.loaderRef = loaderRef;
+    }
 
   private static synchronized java.lang.ClassLoader getBootClassLoader() {
          if (bootClassLoader == null) {
@@ -137,7 +141,7 @@ public class NonCachingClassLoaderRepository
 
     try {
       InputStream is = 
-       loader.getResourceAsStream( classFile + ".class" );
+          loaderRef.getClassLoader().getResourceAsStream(classFile + ".class");
            
       if(is == null) {
        throw new ClassNotFoundException(className + " not found.");