svn merge -c 1376543 FIXES: HADOOP-8632. Configuration leaking class-loaders (Costin Leau via bobby)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1376546 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Joseph Evans 2012-08-23 15:26:42 +00:00
parent 041a1e0a52
commit 4219f17597
3 changed files with 22 additions and 7 deletions

View File

@ -219,6 +219,8 @@ Release 2.0.1-alpha - UNRELEASED
HADOOP-8721. ZKFC should not retry 45 times when attempting a graceful
fence during a failover. (Vinayakumar B via atm)
HADOOP-8632. Configuration leaking class-loaders (Costin Leau via bobby)
BREAKDOWN OF HDFS-3042 SUBTASKS
HADOOP-8220. ZKFailoverController doesn't handle failure to become active

View File

@ -30,6 +30,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.ref.WeakReference;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.ArrayList;
@ -219,8 +220,8 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
private static final CopyOnWriteArrayList<String> defaultResources =
new CopyOnWriteArrayList<String>();
private static final Map<ClassLoader, Map<String, Class<?>>>
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, Class<?>>>();
private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>>
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
/**
* Sentinel value to store negative cache results in {@link #CACHE_CLASSES}.
@ -1495,28 +1496,33 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
* @return the class object, or null if it could not be found.
*/
public Class<?> getClassByNameOrNull(String name) {
Map<String, Class<?>> map;
Map<String, WeakReference<Class<?>>> map;
synchronized (CACHE_CLASSES) {
map = CACHE_CLASSES.get(classLoader);
if (map == null) {
map = Collections.synchronizedMap(
new WeakHashMap<String, Class<?>>());
new WeakHashMap<String, WeakReference<Class<?>>>());
CACHE_CLASSES.put(classLoader, map);
}
}
Class<?> clazz = map.get(name);
Class<?> clazz = null;
WeakReference<Class<?>> ref = map.get(name);
if (ref != null) {
clazz = ref.get();
}
if (clazz == null) {
try {
clazz = Class.forName(name, true, classLoader);
} catch (ClassNotFoundException e) {
// Leave a marker that the class isn't found
map.put(name, NEGATIVE_CACHE_SENTINEL);
map.put(name, new WeakReference<Class<?>>(NEGATIVE_CACHE_SENTINEL));
return null;
}
// two putters can race here, but they'll put the same class
map.put(name, clazz);
map.put(name, new WeakReference<Class<?>>(clazz));
return clazz;
} else if (clazz == NEGATIVE_CACHE_SENTINEL) {
return null; // not found

View File

@ -39,6 +39,7 @@ import java.util.regex.Pattern;
import junit.framework.TestCase;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration.IntegerRanges;
@ -1042,6 +1043,12 @@ public class TestConfiguration extends TestCase {
}
}
public void testGetClassByNameOrNull() throws Exception {
Configuration config = new Configuration();
Class<?> clazz = config.getClassByNameOrNull("java.lang.Object");
assertNotNull(clazz);
}
public static void main(String[] argv) throws Exception {
junit.textui.TestRunner.main(new String[]{
TestConfiguration.class.getName()