HADOOP-8632. Configuration leaking class-loaders (Costin Leau via bobby)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1376543 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f909a1d4d7
commit
42beb56a2e
|
@ -426,6 +426,8 @@ Branch-2 ( Unreleased changes )
|
|||
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
|
||||
|
|
|
@ -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}.
|
||||
|
@ -1531,28 +1532,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
|
||||
|
|
|
@ -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;
|
||||
|
@ -1157,6 +1158,12 @@ public class TestConfiguration extends TestCase {
|
|||
configuration.getPattern("testPattern", Pattern.compile("")).pattern());
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
Loading…
Reference in New Issue