HADOOP-8157. Fix race condition in Configuration that could cause spurious ClassNotFoundExceptions after a GC. Contributed by Todd Lipcon.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1303634 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0c4acdc176
commit
76817c28a2
@ -257,6 +257,9 @@ Release 0.23.3 - UNRELEASED
|
|||||||
|
|
||||||
HADOOP-8191. SshFenceByTcpPort uses netcat incorrectly (todd)
|
HADOOP-8191. SshFenceByTcpPort uses netcat incorrectly (todd)
|
||||||
|
|
||||||
|
HADOOP-8157. Fix race condition in Configuration that could cause spurious
|
||||||
|
ClassNotFoundExceptions after a GC. (todd)
|
||||||
|
|
||||||
BREAKDOWN OF HADOOP-7454 SUBTASKS
|
BREAKDOWN OF HADOOP-7454 SUBTASKS
|
||||||
|
|
||||||
HADOOP-7455. HA: Introduce HA Service Protocol Interface. (suresh)
|
HADOOP-7455. HA: Introduce HA Service Protocol Interface. (suresh)
|
||||||
|
@ -189,6 +189,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|||||||
private static final Map<ClassLoader, Map<String, Class<?>>>
|
private static final Map<ClassLoader, Map<String, Class<?>>>
|
||||||
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, Class<?>>>();
|
CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, Class<?>>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sentinel value to store negative cache results in {@link #CACHE_CLASSES}.
|
||||||
|
*/
|
||||||
|
private static final Class<?> NEGATIVE_CACHE_SENTINEL =
|
||||||
|
NegativeCacheSentinel.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the mapping of key to the resource which modifies or loads
|
* Stores the mapping of key to the resource which modifies or loads
|
||||||
* the key most recently
|
* the key most recently
|
||||||
@ -1194,24 +1200,24 @@ public Class<?> getClassByNameOrNull(String name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> clazz = null;
|
Class<?> clazz = map.get(name);
|
||||||
if (!map.containsKey(name)) {
|
if (clazz == null) {
|
||||||
try {
|
try {
|
||||||
clazz = Class.forName(name, true, classLoader);
|
clazz = Class.forName(name, true, classLoader);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
map.put(name, null); //cache negative that class is not found
|
// Leave a marker that the class isn't found
|
||||||
|
map.put(name, NEGATIVE_CACHE_SENTINEL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// two putters can race here, but they'll put the same class
|
// two putters can race here, but they'll put the same class
|
||||||
map.put(name, clazz);
|
map.put(name, clazz);
|
||||||
} else { // check already performed on this class name
|
return clazz;
|
||||||
clazz = map.get(name);
|
} else if (clazz == NEGATIVE_CACHE_SENTINEL) {
|
||||||
if (clazz == null) { // found the negative
|
return null; // not found
|
||||||
return null;
|
} else {
|
||||||
}
|
// cache hit
|
||||||
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clazz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1915,4 +1921,10 @@ private static void addDeprecatedKeys() {
|
|||||||
Configuration.addDeprecation("fs.default.name",
|
Configuration.addDeprecation("fs.default.name",
|
||||||
new String[]{CommonConfigurationKeys.FS_DEFAULT_NAME_KEY});
|
new String[]{CommonConfigurationKeys.FS_DEFAULT_NAME_KEY});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unique class which is used as a sentinel value in the caching
|
||||||
|
* for getClassByName. {@see Configuration#getClassByNameOrNull(String)}
|
||||||
|
*/
|
||||||
|
private static abstract class NegativeCacheSentinel {}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user