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 {}
 }


Reply via email to