Skip to content

Commit

Permalink
wrapping classes with WeakRefs in CLASS_CACHE
Browse files Browse the repository at this point in the history
HADOOP-8632
  • Loading branch information
Costin Leau committed Aug 16, 2012
1 parent 7a3427d commit 518c398
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
Expand Up @@ -30,6 +30,7 @@
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;
Expand Down Expand Up @@ -219,8 +220,8 @@ public String toString() {
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}.
Expand Down Expand Up @@ -1531,28 +1532,33 @@ public Class<?> getClassByName(String name) throws ClassNotFoundException {
* @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
Expand Down
Expand Up @@ -39,6 +39,7 @@

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;
Expand Down Expand Up @@ -1157,6 +1158,12 @@ public void testSetPattern() {
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()
Expand Down

0 comments on commit 518c398

Please sign in to comment.