You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2010/08/09 04:36:35 UTC
svn commit: r983505 - in
/geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel:
ClassLoading.java config/MultiParentClassLoader.java
Author: xuhaihong
Date: Mon Aug 9 02:36:35 2010
New Revision: 983505
URL: http://svn.apache.org/viewvc?rev=983505&view=rev
Log:
GERONIMO-4217 Check for all data primitive types when shortcutting to the primordial classloader
Modified:
geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/ClassLoading.java
geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java
Modified: geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/ClassLoading.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/ClassLoading.java?rev=983505&r1=983504&r2=983505&view=diff
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/ClassLoading.java (original)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/ClassLoading.java Mon Aug 9 02:36:35 2010
@@ -49,15 +49,18 @@ public class ClassLoading {
/**
* Table for mapping primitive class names/signatures to the implementing
* class object
+ * initialCapacity is calculated from 12 * 0.75 = 9
*/
- private static final HashMap PRIMITIVE_CLASS_MAP = new HashMap();
+ private static final HashMap<String, Class<?>> HUMAN_READABLE_PRIMITIVE_CLASS_MAP = new HashMap<String, Class<?>>(12);
+
+ private static final HashMap<String, Class<?>> BINARY_NAME_PRIMITIVE_CLASS_MAP = new HashMap<String, Class<?>>(12);
/**
* Table for mapping primitive classes back to their name signature type, which
* allows a reverse mapping to be performed from a class object into a resolvable
* signature.
*/
- private static final HashMap CLASS_TO_SIGNATURE_MAP = new HashMap();
+ private static final HashMap<Class<?>, String> CLASS_TO_SIGNATURE_MAP = new HashMap<Class<?>, String>(12);
/**
@@ -65,24 +68,24 @@ public class ClassLoading {
* human readable name and the method signature shorthand type.
*/
static {
- PRIMITIVE_CLASS_MAP.put("boolean", boolean.class);
- PRIMITIVE_CLASS_MAP.put("Z", boolean.class);
- PRIMITIVE_CLASS_MAP.put("byte", byte.class);
- PRIMITIVE_CLASS_MAP.put("B", byte.class);
- PRIMITIVE_CLASS_MAP.put("char", char.class);
- PRIMITIVE_CLASS_MAP.put("C", char.class);
- PRIMITIVE_CLASS_MAP.put("short", short.class);
- PRIMITIVE_CLASS_MAP.put("S", short.class);
- PRIMITIVE_CLASS_MAP.put("int", int.class);
- PRIMITIVE_CLASS_MAP.put("I", int.class);
- PRIMITIVE_CLASS_MAP.put("long", long.class);
- PRIMITIVE_CLASS_MAP.put("J", long.class);
- PRIMITIVE_CLASS_MAP.put("float", float.class);
- PRIMITIVE_CLASS_MAP.put("F", float.class);
- PRIMITIVE_CLASS_MAP.put("double", double.class);
- PRIMITIVE_CLASS_MAP.put("D", double.class);
- PRIMITIVE_CLASS_MAP.put("void", void.class);
- PRIMITIVE_CLASS_MAP.put("V", void.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("boolean", boolean.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("Z", boolean.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("byte", byte.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("B", byte.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("char", char.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("C", char.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("short", short.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("S", short.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("int", int.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("I", int.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("long", long.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("J", long.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("float", float.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("F", float.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("double", double.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("D", double.class);
+ HUMAN_READABLE_PRIMITIVE_CLASS_MAP.put("void", void.class);
+ BINARY_NAME_PRIMITIVE_CLASS_MAP.put("V", void.class);
// Now build a reverse mapping table. The table above has a many-to-one mapping for
// class names. To do the reverse, we need to pick just one. As long as the
@@ -123,6 +126,16 @@ public class ClassLoading {
if (classLoader == null) {
throw new IllegalArgumentException("classLoader is null");
}
+
+ //First check the human readable primitive class from cached map
+ Class<?> resolvedClass;
+ if (className.length() <= 7) {
+ resolvedClass = HUMAN_READABLE_PRIMITIVE_CLASS_MAP.get(className);
+ if (resolvedClass != null) {
+ return resolvedClass;
+ }
+ }
+
// The easiest case is a proper class name. We just have the class loader resolve this.
// If the class loader throws a ClassNotFoundException, then we need to check each of the
// special name encodings we support.
@@ -135,7 +148,7 @@ public class ClassLoading {
// The second easiest version to resolve is a direct map to a primitive type name
// or method signature. Check our name-to-class map for one of those.
- Class resolvedClass = (Class) PRIMITIVE_CLASS_MAP.get(className);
+ resolvedClass = BINARY_NAME_PRIMITIVE_CLASS_MAP.get(className);
if (resolvedClass != null) {
return resolvedClass;
}
@@ -250,7 +263,7 @@ public class ClassLoading {
// we're down to the base type. If this is a primitive, then
// we poke in the single-character type specifier.
if (type.isPrimitive()) {
- name.append((String) CLASS_TO_SIGNATURE_MAP.get(type));
+ name.append(CLASS_TO_SIGNATURE_MAP.get(type));
}
// a "normal" class. This gets expressing using the "Lmy.class.name;" syntax.
else {
@@ -319,7 +332,7 @@ public class ClassLoading {
*/
public static Class[] reduceInterfaces(Class[] source) {
// use a copy of the sorce array
- source = (Class[]) source.clone();
+ source = source.clone();
for (int leftIndex = 0; leftIndex < source.length-1; leftIndex++) {
Class left = source[leftIndex];
Modified: geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java?rev=983505&r1=983504&r2=983505&view=diff
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java (original)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java Mon Aug 9 02:36:35 2010
@@ -64,30 +64,30 @@ public class MultiParentClassLoader exte
private boolean destroyed = false;
private Map<String,Object> resourcesNotFound = new ConcurrentHashMap<String,Object>();
- // I used this pattern as its temporary and with the static final we get compile time
+ // I used this pattern as its temporary and with the static final we get compile time
// optimizations.
private final static int classLoaderSearchMode;
private final static int ORIGINAL_SEARCH = 1;
private final static int OPTIMIZED_SEARCH = 2;
-
+
static {
// Extract the classLoaderSearchMode if specified. If not, default to "safe".
- String mode = System.getProperty("Xorg.apache.geronimo.kernel.config.MPCLSearchOption");
- int runtimeMode = OPTIMIZED_SEARCH; // Default to optimized
- String runtimeModeMessage = "Original Classloading";
- if (mode != null) {
- if (mode.equals("safe")) {
+ String mode = System.getProperty("Xorg.apache.geronimo.kernel.config.MPCLSearchOption");
+ int runtimeMode = OPTIMIZED_SEARCH; // Default to optimized
+ String runtimeModeMessage = "Original Classloading";
+ if (mode != null) {
+ if (mode.equals("safe")) {
runtimeMode = ORIGINAL_SEARCH;
runtimeModeMessage = "Safe ClassLoading";
- } else if (mode.equals("optimized"))
- runtimeMode = OPTIMIZED_SEARCH;
- }
-
- classLoaderSearchMode = runtimeMode;
- log.info("ClassLoading behaviour has changed. The "+runtimeModeMessage+" mode is in effect. If you are experiencing a problem\n"+
- "you can change the behaviour by specifying -DXorg.apache.geronimo.kernel.config.MPCLSearchOption= property. Specify \n"+
- "=\"safe\" to revert to the original behaviour. This is a temporary change until we decide whether or not to make it\n"+
- "permanent for the 2.0 release");
+ } else if (mode.equals("optimized"))
+ runtimeMode = OPTIMIZED_SEARCH;
+ }
+
+ classLoaderSearchMode = runtimeMode;
+ log.info("ClassLoading behaviour has changed. The "+runtimeModeMessage+" mode is in effect. If you are experiencing a problem\n"+
+ "you can change the behaviour by specifying -DXorg.apache.geronimo.kernel.config.MPCLSearchOption= property. Specify \n"+
+ "=\"safe\" to revert to the original behaviour. This is a temporary change until we decide whether or not to make it\n"+
+ "permanent for the 2.0 release");
}
/**
@@ -271,19 +271,19 @@ public class MultiParentClassLoader exte
}
/**
- * TODO This method should be removed and replaced with the best classLoading option. Its intent is to
+ * TODO This method should be removed and replaced with the best classLoading option. Its intent is to
* provide a way for folks to switch back to the old classLoader if this fix breaks something.
*/
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- if (classLoaderSearchMode == ORIGINAL_SEARCH)
+ if (classLoaderSearchMode == ORIGINAL_SEARCH)
return loadSafeClass(name, resolve);
else
return loadOptimizedClass(name, resolve);
}
-
+
/**
* This method executes the old class loading behaviour before optimization.
- *
+ *
* @param name
* @param resolve
* @return
@@ -305,15 +305,7 @@ public class MultiParentClassLoader exte
// The order is based on profiling the server. It may not be optimal for all
// workloads.
- if (name.startsWith("java.") ||
- name.equals("boolean") ||
- name.equals("int") ||
- name.equals("double") ||
- name.equals("long") ||
- name.equals("short") ||
- name.equals("float") ||
- name.equals("byte") ||
- name.equals("char")) {
+ if (name.startsWith("java.")) {
Class clazz = ClassLoader.getSystemClassLoader().loadClass(name);
return resolveClass(clazz, resolve);
}
@@ -358,22 +350,22 @@ public class MultiParentClassLoader exte
}
throw new ClassNotFoundException(name + " in classloader " + id);
- }
-
+ }
+
/**
- *
+ *
* Optimized classloading.
- *
- * This method is the normal way to resolve class loads. This method recursively calls its parents to resolve
+ *
+ * This method is the normal way to resolve class loads. This method recursively calls its parents to resolve
* classloading requests. Here is the sequence of operations:
- *
+ *
* 1. Call findLoadedClass to see if we already have this class loaded.
* 2. If this class is a java.* or data primitive class, call the SystemClassLoader.
* 3. If inverse loading and class is not in the non-overridable list, check the local ClassLoader.
* 4. If the class is not a hidden class, search our parents, recursively. Keeping track of which parents have already been called.
* Since MultiParentClassLoaders can appear more than once we do not search an already searched ClassLoader.
- * 5. Finally, search this ClassLoader.
- *
+ * 5. Finally, search this ClassLoader.
+ *
*/
protected synchronized Class<?> loadOptimizedClass(String name, boolean resolve) throws ClassNotFoundException {
@@ -390,15 +382,7 @@ public class MultiParentClassLoader exte
//
// The order is based on profiling the server. It may not be optimal for all
// workloads.
- if (name.startsWith("java.") ||
- name.equals("boolean") ||
- name.equals("int") ||
- name.equals("double") ||
- name.equals("long") ||
- name.equals("short") ||
- name.equals("float") ||
- name.equals("byte") ||
- name.equals("char")) {
+ if (name.startsWith("java.")) {
try {
return resolveClass(findSystemClass(name), resolve);
} catch (ClassNotFoundException cnfe) {
@@ -416,7 +400,7 @@ public class MultiParentClassLoader exte
} catch (ClassNotFoundException ignored) {
}
}
-
+
//
// Check parent class loaders
//
@@ -446,13 +430,13 @@ public class MultiParentClassLoader exte
throw new ClassNotFoundException(name + " in classloader " + id);
}
-
+
/**
* This method is an internal hook that allows us to be performant on Class lookups when multiparent
* classloaders are involved. We can bypass certain lookups that have already occurred in the initiating
* classloader. Also, we track the classLoaders that are visited by adding them to an already vistied list.
* In this way, we can bypass redundant checks for the same class.
- *
+ *
* @param name
* @param visitedClassLoaders
* @return
@@ -478,7 +462,7 @@ public class MultiParentClassLoader exte
// ignore
}
}
-
+
//
// if we are not using inverse class loading, check local urls now
//
@@ -494,12 +478,12 @@ public class MultiParentClassLoader exte
}
/**
- * In order to optimize the classLoading process and visit a directed set of
- * classloaders this internal method for Geronimo MultiParentClassLoaders
+ * In order to optimize the classLoading process and visit a directed set of
+ * classloaders this internal method for Geronimo MultiParentClassLoaders
* is used. Effectively, as each classloader is visited it is passed a linked
* list of classloaders that have already been visited and can safely be skipped.
* This method assumes the context of an MPCL and is not for use external to this class.
- *
+ *
* @param name
* @param visitedClassLoaders
* @return
@@ -522,7 +506,7 @@ public class MultiParentClassLoader exte
log.debug("Failed findClass=" + name, me);
}
}
- }
+ }
// To avoid yet another CNFE we'll simply return null and let the caller handle appropriately.
return null;
}
@@ -593,10 +577,10 @@ public class MultiParentClassLoader exte
}
}
- //
+ //
// Resource not found -- no need to search for it again
// Use the name as key and value. We don't care about the value and it needs to be non-null.
- //
+ //
resourcesNotFound.put(name, name);
return null;
@@ -719,5 +703,5 @@ public class MultiParentClassLoader exte
ClassLoaderRegistry.remove(this);
super.finalize();
}
-
+
}