Author: jlowe
Date: Wed Jan 16 21:26:04 2013
New Revision: 1434412
URL: http://svn.apache.org/viewvc?rev=1434412&view=rev
Log:
svn merge -c 1303634 FIXES: HADOOP-8157. Fix race condition in Configuration
that could cause spurious ClassNotFoundExceptions after a GC. Contributed by
Todd Lipcon.
Modified:
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java
Modified:
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1434412&r1=1434411&r2=1434412&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
(original)
+++
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
Wed Jan 16 21:26:04 2013
@@ -12,6 +12,9 @@ Release 0.23.7 - UNRELEASED
BUG FIXES
+ HADOOP-8157. Fix race condition in Configuration that could cause spurious
+ ClassNotFoundExceptions after a GC. (todd)
+
Release 0.23.6 - UNRELEASED
INCOMPATIBLE CHANGES
Modified:
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java?rev=1434412&r1=1434411&r2=1434412&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java
(original)
+++
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java
Wed Jan 16 21:26:04 2013
@@ -223,6 +223,12 @@ public class Configuration implements It
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
* the key most recently
*/
@@ -1474,24 +1480,24 @@ public class Configuration implements It
}
}
- Class<?> clazz = null;
- if (!map.containsKey(name)) {
+ Class<?> clazz = map.get(name);
+ if (clazz == null) {
try {
clazz = Class.forName(name, true, classLoader);
} 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;
}
// two putters can race here, but they'll put the same class
map.put(name, clazz);
- } else { // check already performed on this class name
- clazz = map.get(name);
- if (clazz == null) { // found the negative
- return null;
- }
+ return clazz;
+ } else if (clazz == NEGATIVE_CACHE_SENTINEL) {
+ return null; // not found
+ } else {
+ // cache hit
+ return clazz;
}
-
- return clazz;
}
/**
@@ -2248,4 +2254,10 @@ public class Configuration implements It
Configuration.addDeprecation("dfs.umaskmode",
new String[]{CommonConfigurationKeys.FS_PERMISSIONS_UMASK_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 {}
}