You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by us...@apache.org on 2010/02/12 12:21:59 UTC
svn commit: r909361 - in /lucene/java/branches/lucene_2_9: CHANGES.txt
src/java/org/apache/lucene/util/AttributeSource.java
Author: uschindler
Date: Fri Feb 12 11:21:58 2010
New Revision: 909361
URL: http://svn.apache.org/viewvc?rev=909361&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.
Modified:
lucene/java/branches/lucene_2_9/CHANGES.txt
lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/util/AttributeSource.java
Modified: lucene/java/branches/lucene_2_9/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/CHANGES.txt?rev=909361&r1=909360&r2=909361&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/CHANGES.txt (original)
+++ lucene/java/branches/lucene_2_9/CHANGES.txt Fri Feb 12 11:21:58 2010
@@ -35,6 +35,11 @@
implementation class when interface was loaded by a different
class loader. (Uwe Schindler, reported on java-user by Ahmed El-dawy)
+ * 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)
+
API Changes
* LUCENE-2190: Added setNextReader method to CustomScoreQuery, which
Modified: lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/util/AttributeSource.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/util/AttributeSource.java?rev=909361&r1=909360&r2=909361&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/util/AttributeSource.java (original)
+++ lucene/java/branches/lucene_2_9/src/java/org/apache/lucene/util/AttributeSource.java Fri Feb 12 11:21:58 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;
@@ -55,7 +56,7 @@
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();
+ private static final WeakHashMap/*<Class<? extends Attribute>, WeakReference<Class<? extends AttributeImpl>>>*/ attClassImplMap = new WeakHashMap();
private DefaultAttributeFactory() {}
@@ -71,12 +72,13 @@
private static Class getClassForInterface(Class attClass) {
synchronized(attClassImplMap) {
- Class clazz = (Class) attClassImplMap.get(attClass);
+ final WeakReference ref = (WeakReference) attClassImplMap.get(attClass);
+ Class clazz = (ref == null) ? null : ((Class) ref.get());
if (clazz == null) {
try {
- attClassImplMap.put(attClass,
+ attClassImplMap.put(attClass, new WeakReference(
clazz = Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader())
- );
+ ));
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Could not find implementing class for " + attClass.getName());
}
@@ -173,7 +175,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();
+ private static final WeakHashMap/*<Class<? extends AttributeImpl>,LinkedList<WeakReference<Class<? extends Attribute>>>>*/
+ knownImplClasses = new WeakHashMap();
/** Adds a custom AttributeImpl instance with one or more Attribute interfaces. */
public void addAttributeImpl(final AttributeImpl att) {
@@ -183,6 +186,8 @@
synchronized(knownImplClasses) {
foundInterfaces = (LinkedList) knownImplClasses.get(clazz);
if (foundInterfaces == null) {
+ // 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());
// find all interfaces that this attribute instance implements
// and that extend the Attribute interface
@@ -192,7 +197,7 @@
for (int i = 0; i < interfaces.length; i++) {
final Class curInterface = interfaces[i];
if (curInterface != Attribute.class && Attribute.class.isAssignableFrom(curInterface)) {
- foundInterfaces.add(curInterface);
+ foundInterfaces.add(new WeakReference(curInterface));
}
}
actClazz = actClazz.getSuperclass();
@@ -202,7 +207,10 @@
// add all interfaces of this AttributeImpl to the maps
for (Iterator it = foundInterfaces.iterator(); it.hasNext(); ) {
- final Class curInterface = (Class) it.next();
+ final WeakReference curInterfaceRef = (WeakReference) it.next();
+ final Class curInterface = (Class) 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()