lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From uschind...@apache.org
Subject svn commit: r909360 - in /lucene/java/trunk: CHANGES.txt src/java/org/apache/lucene/util/AttributeSource.java src/java/org/apache/lucene/util/VirtualMethod.java
Date Fri, 12 Feb 2010 11:20:36 GMT
Author: uschindler
Date: Fri Feb 12 11:20:35 2010
New Revision: 909360

URL: http://svn.apache.org/viewvc?rev=909360&view=rev
Log:
LUCENE-2260: Fix AttributeSource to not hold a strong reference to the Attribute/AttributeImpl
classes which prevents unloading of custom attributes loaded by other classloaders. The same
fix applies to VirtualMethod (3.1 only).

Modified:
    lucene/java/trunk/CHANGES.txt
    lucene/java/trunk/src/java/org/apache/lucene/util/AttributeSource.java
    lucene/java/trunk/src/java/org/apache/lucene/util/VirtualMethod.java

Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=909360&r1=909359&r2=909360&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Fri Feb 12 11:20:35 2010
@@ -118,6 +118,11 @@
   termIndexInterval (default 128) * ~2.1 billion = ~274 billion.
   (Tom Burton-West via Mike McCandless)
   
+* LUCENE-2260: Fixed AttributeSource to not hold a strong
+  reference to the Attribute/AttributeImpl classes which prevents
+  unloading of custom attributes loaded by other classloaders
+  (e.g. in Solr plugins).  (Uwe Schindler)
+
 New features
 
 * LUCENE-2128: Parallelized fetching document frequencies during weight

Modified: lucene/java/trunk/src/java/org/apache/lucene/util/AttributeSource.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/AttributeSource.java?rev=909360&r1=909359&r2=909360&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/util/AttributeSource.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/util/AttributeSource.java Fri Feb 12 11:20:35
2010
@@ -17,11 +17,12 @@
  * limitations under the License.
  */
 
+import java.lang.ref.WeakReference;
 import java.util.Collections;
 import java.util.NoSuchElementException;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.IdentityHashMap;
+import java.util.WeakHashMap;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -54,8 +55,8 @@
     public static final AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new DefaultAttributeFactory();
     
     private static final class DefaultAttributeFactory extends AttributeFactory {
-      private static final IdentityHashMap<Class<? extends Attribute>, Class<?
extends AttributeImpl>> attClassImplMap =
-        new IdentityHashMap<Class<? extends Attribute>, Class<? extends AttributeImpl>>();
+      private static final WeakHashMap<Class<? extends Attribute>, WeakReference<Class<?
extends AttributeImpl>>> attClassImplMap =
+        new WeakHashMap<Class<? extends Attribute>, WeakReference<Class<?
extends AttributeImpl>>>();
       
       private DefaultAttributeFactory() {}
     
@@ -72,12 +73,15 @@
       
       private static Class<? extends AttributeImpl> getClassForInterface(Class<?
extends Attribute> attClass) {
         synchronized(attClassImplMap) {
-          Class<? extends AttributeImpl> clazz = attClassImplMap.get(attClass);
+          final WeakReference<Class<? extends AttributeImpl>> ref = attClassImplMap.get(attClass);
+          Class<? extends AttributeImpl> clazz = (ref == null) ? null : ref.get();
           if (clazz == null) {
             try {
               attClassImplMap.put(attClass,
-                clazz = Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader())
-                .asSubclass(AttributeImpl.class)
+                new WeakReference<Class<? extends AttributeImpl>>(
+                  clazz = Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader())
+                  .asSubclass(AttributeImpl.class)
+                )
               );
             } catch (ClassNotFoundException e) {
               throw new IllegalArgumentException("Could not find implementing class for "
+ attClass.getName());
@@ -173,8 +177,8 @@
   }
   
   /** a cache that stores all interfaces for known implementation classes for performance
(slow reflection) */
-  private static final IdentityHashMap<Class<? extends AttributeImpl>,LinkedList<Class<?
extends Attribute>>> knownImplClasses =
-    new IdentityHashMap<Class<? extends AttributeImpl>,LinkedList<Class<?
extends Attribute>>>();
+  private static final WeakHashMap<Class<? extends AttributeImpl>,LinkedList<WeakReference<Class<?
extends Attribute>>>> knownImplClasses =
+    new WeakHashMap<Class<? extends AttributeImpl>,LinkedList<WeakReference<Class<?
extends Attribute>>>>();
   
   /** <b>Expert:</b> Adds a custom AttributeImpl instance with one or more Attribute
interfaces.
    * <p><font color="red"><b>Please note:</b> It is not guaranteed,
that <code>att</code> is added to
@@ -187,18 +191,20 @@
   public void addAttributeImpl(final AttributeImpl att) {
     final Class<? extends AttributeImpl> clazz = att.getClass();
     if (attributeImpls.containsKey(clazz)) return;
-    LinkedList<Class<? extends Attribute>> foundInterfaces;
+    LinkedList<WeakReference<Class<? extends Attribute>>> foundInterfaces;
     synchronized(knownImplClasses) {
       foundInterfaces = knownImplClasses.get(clazz);
       if (foundInterfaces == null) {
-        knownImplClasses.put(clazz, foundInterfaces = new LinkedList<Class<? extends
Attribute>>());
+        // we have a strong reference to the class instance holding all interfaces in the
list (parameter "att"),
+        // so all WeakReferences are never evicted by GC
+        knownImplClasses.put(clazz, foundInterfaces = new LinkedList<WeakReference<Class<?
extends Attribute>>>());
         // find all interfaces that this attribute instance implements
         // and that extend the Attribute interface
         Class<?> actClazz = clazz;
         do {
           for (Class<?> curInterface : actClazz.getInterfaces()) {
             if (curInterface != Attribute.class && Attribute.class.isAssignableFrom(curInterface))
{
-              foundInterfaces.add(curInterface.asSubclass(Attribute.class));
+              foundInterfaces.add(new WeakReference<Class<? extends Attribute>>(curInterface.asSubclass(Attribute.class)));
             }
           }
           actClazz = actClazz.getSuperclass();
@@ -207,7 +213,10 @@
     }
     
     // add all interfaces of this AttributeImpl to the maps
-    for (Class<? extends Attribute> curInterface : foundInterfaces) {
+    for (WeakReference<Class<? extends Attribute>> curInterfaceRef : foundInterfaces)
{
+      final Class<? extends Attribute> curInterface = curInterfaceRef.get();
+      assert (curInterface != null) :
+        "We have a strong reference on the class holding the interfaces, so they should never
get evicted";
       // Attribute is a superclass of this interface
       if (!attributes.containsKey(curInterface)) {
         // invalidate state to force recomputation in captureState()

Modified: lucene/java/trunk/src/java/org/apache/lucene/util/VirtualMethod.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/VirtualMethod.java?rev=909360&r1=909359&r2=909360&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/util/VirtualMethod.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/util/VirtualMethod.java Fri Feb 12 11:20:35
2010
@@ -20,7 +20,7 @@
 import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.IdentityHashMap;
+import java.util.WeakHashMap;
 import java.util.Set;
 
 /**
@@ -64,8 +64,8 @@
   private final Class<C> baseClass;
   private final String method;
   private final Class<?>[] parameters;
-  private final IdentityHashMap<Class<? extends C>, Integer> cache =
-    new IdentityHashMap<Class<? extends C>, Integer>();
+  private final WeakHashMap<Class<? extends C>, Integer> cache =
+    new WeakHashMap<Class<? extends C>, Integer>();
 
   /**
    * Creates a new instance for the given {@code baseClass} and method declaration.



Mime
View raw message