You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2009/11/11 01:39:44 UTC
svn commit: r834727 - in /ofbiz/trunk/framework:
base/src/org/ofbiz/base/util/CachedClassLoader.java
entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java
Author: adrianc
Date: Wed Nov 11 00:39:44 2009
New Revision: 834727
URL: http://svn.apache.org/viewvc?rev=834727&view=rev
Log:
Some work on CachedClassLoader.java. Fixed non-thread-safe code, converted HashMap and HashSet to Javolution classes, added a registerClass method, and simplified the Init interface.
Modified:
ofbiz/trunk/framework/base/src/org/ofbiz/base/util/CachedClassLoader.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java
Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/CachedClassLoader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/CachedClassLoader.java?rev=834727&r1=834726&r2=834727&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/CachedClassLoader.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/CachedClassLoader.java Wed Nov 11 00:39:44 2009
@@ -20,12 +20,15 @@
import java.net.URL;
import java.net.URLClassLoader;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
+
import javax.imageio.spi.ServiceRegistry;
+import javolution.util.FastMap;
+import javolution.util.FastSet;
+
/**
* Caching Class Loader
*
@@ -33,99 +36,104 @@
public class CachedClassLoader extends URLClassLoader {
public interface Init {
- void loadClasses(ClassLoader loader, Map<String, Class<?>> classNameMap) throws ClassNotFoundException;
+ void loadClasses(ClassLoader loader) throws ClassNotFoundException;
}
public static final String module = CachedClassLoader.class.getName();
+ public static final Map<String, Class<?>> globalClassNameClassMap = FastMap.newInstance();
+ public static final Set<String> globalBadClassNameSet = FastSet.newInstance();
+ public static final Map<String, URL> globalResourceMap = FastMap.newInstance();
+ public static final Set<String> globalBadResourceNameSet = FastSet.newInstance();
private String contextName;
-
- public static Map<String, Class<?>> globalClassNameClassMap = new HashMap<String, Class<?>>();
- public static HashSet<String> globalBadClassNameSet = new HashSet<String>();
-
- public Map<String, Class<?>> localClassNameClassMap = new HashMap<String, Class<?>>();
- public HashSet<String> localBadClassNameSet = new HashSet<String>();
-
- public static Map<String, URL> globalResourceMap = new HashMap<String, URL>();
- public static HashSet<String> globalBadResourceNameSet = new HashSet<String>();
-
- public Map<String, URL> localResourceMap = new HashMap<String, URL>();
- public HashSet<String> localBadResourceNameSet = new HashSet<String>();
+ protected final Map<String, Class<?>> localClassNameClassMap = FastMap.newInstance();
+ protected final Set<String> localBadClassNameSet = FastSet.newInstance();
+ protected final Map<String, URL> localResourceMap = FastMap.newInstance();
+ protected final Set<String> localBadResourceNameSet = FastSet.newInstance();
static {
// setup some commonly used classes...
- globalClassNameClassMap.put("Object", java.lang.Object.class);
- globalClassNameClassMap.put("java.lang.Object", java.lang.Object.class);
-
- globalClassNameClassMap.put("String", java.lang.String.class);
- globalClassNameClassMap.put("java.lang.String", java.lang.String.class);
-
- globalClassNameClassMap.put("Boolean", java.lang.Boolean.class);
- globalClassNameClassMap.put("java.lang.Boolean", java.lang.Boolean.class);
-
- globalClassNameClassMap.put("BigDecimal", java.math.BigDecimal.class);
- globalClassNameClassMap.put("java.math.BigDecimal", java.math.BigDecimal.class);
- globalClassNameClassMap.put("Double", java.lang.Double.class);
- globalClassNameClassMap.put("java.lang.Double", java.lang.Double.class);
- globalClassNameClassMap.put("Float", java.lang.Float.class);
- globalClassNameClassMap.put("java.lang.Float", java.lang.Float.class);
- globalClassNameClassMap.put("Long", java.lang.Long.class);
- globalClassNameClassMap.put("java.lang.Long", java.lang.Long.class);
- globalClassNameClassMap.put("Integer", java.lang.Integer.class);
- globalClassNameClassMap.put("java.lang.Integer", java.lang.Integer.class);
- globalClassNameClassMap.put("Short", java.lang.Short.class);
- globalClassNameClassMap.put("java.lang.Short", java.lang.Short.class);
-
- globalClassNameClassMap.put("Byte", java.lang.Byte.class);
- globalClassNameClassMap.put("java.lang.Byte", java.lang.Byte.class);
- globalClassNameClassMap.put("Character", java.lang.Character.class);
- globalClassNameClassMap.put("java.lang.Character", java.lang.Character.class);
-
- globalClassNameClassMap.put("Timestamp", java.sql.Timestamp.class);
- globalClassNameClassMap.put("java.sql.Timestamp", java.sql.Timestamp.class);
- globalClassNameClassMap.put("Time", java.sql.Time.class);
- globalClassNameClassMap.put("java.sql.Time", java.sql.Time.class);
- globalClassNameClassMap.put("Date", java.sql.Date.class);
- globalClassNameClassMap.put("java.sql.Date", java.sql.Date.class);
-
- globalClassNameClassMap.put("Locale", java.util.Locale.class);
- globalClassNameClassMap.put("java.util.Locale", java.util.Locale.class);
-
- globalClassNameClassMap.put("java.util.Date", java.util.Date.class);
- globalClassNameClassMap.put("Collection", java.util.Collection.class);
- globalClassNameClassMap.put("java.util.Collection", java.util.Collection.class);
- globalClassNameClassMap.put("List", java.util.List.class);
- globalClassNameClassMap.put("java.util.List", java.util.List.class);
- globalClassNameClassMap.put("Set", java.util.Set.class);
- globalClassNameClassMap.put("java.util.Set", java.util.Set.class);
- globalClassNameClassMap.put("Map", java.util.Map.class);
- globalClassNameClassMap.put("java.util.Map", java.util.Map.class);
- globalClassNameClassMap.put("HashMap", java.util.HashMap.class);
- globalClassNameClassMap.put("java.util.HashMap", java.util.HashMap.class);
+ registerClass(java.lang.Object.class);
+ registerClass(java.lang.String.class);
+ registerClass(java.lang.Boolean.class);
+ registerClass(java.math.BigDecimal.class);
+ registerClass(java.lang.Double.class);
+ registerClass(java.lang.Float.class);
+ registerClass(java.lang.Long.class);
+ registerClass(java.lang.Integer.class);
+ registerClass(java.lang.Short.class);
+ registerClass(java.lang.Byte.class);
+ registerClass(java.lang.Character.class);
+ registerClass(java.sql.Timestamp.class);
+ registerClass(java.sql.Time.class);
+ registerClass(java.sql.Date.class);
+ registerClass(java.util.Locale.class);
+ registerClass(java.util.Date.class);
+ registerClass(java.util.Collection.class);
+ registerClass(java.util.List.class);
+ registerClass(java.util.Set.class);
+ registerClass(java.util.Map.class);
+ registerClass(java.util.HashMap.class);
// setup the primitive types
- globalClassNameClassMap.put("boolean", Boolean.TYPE);
- globalClassNameClassMap.put("short", Short.TYPE);
- globalClassNameClassMap.put("int", Integer.TYPE);
- globalClassNameClassMap.put("long", Long.TYPE);
- globalClassNameClassMap.put("float", Float.TYPE);
- globalClassNameClassMap.put("double", Double.TYPE);
- globalClassNameClassMap.put("byte", Byte.TYPE);
- globalClassNameClassMap.put("char", Character.TYPE);
+ registerClass(Boolean.TYPE);
+ registerClass(Short.TYPE);
+ registerClass(Integer.TYPE);
+ registerClass(Long.TYPE);
+ registerClass(Float.TYPE);
+ registerClass(Double.TYPE);
+ registerClass(Byte.TYPE);
+ registerClass(Character.TYPE);
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ // setup OFBiz classes
+ registerClass(org.ofbiz.base.util.TimeDuration.class);
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
Iterator<Init> cachedClassLoaders = ServiceRegistry.lookupProviders(Init.class, loader);
while (cachedClassLoaders.hasNext()) {
Init cachedClassLoader = cachedClassLoaders.next();
try {
- cachedClassLoader.loadClasses(loader, globalClassNameClassMap);
- } catch (ClassNotFoundException e) {
+ cachedClassLoader.loadClasses(loader);
+ } catch (Exception e) {
Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
}
}
}
+ /** Registers a <code>Class</code> with the class loader. The class will be
+ * added to the global class cache, and an alias name will be created.
+ * <p>The alias name is the right-most portion of the binary name. Example:
+ * the alias for <code>java.lang.Object</code> is <code>Object</code>.
+ * If the alias already exists for another class, then no alias is created
+ * (the previously aliased class takes precedence).</p>
+ *
+ * @param theClass The <code>Class</code> to register
+ * @throws IllegalArgumentException If <code>theClass</code> is an array
+ */
+ public static void registerClass(Class<?> theClass) {
+ if (theClass.isArray()) {
+ throw new IllegalArgumentException("theClass cannot be an array");
+ }
+ synchronized(globalClassNameClassMap) {
+ Object obj = globalClassNameClassMap.get(theClass.getName());
+ if (obj == null) {
+ globalClassNameClassMap.put(theClass.getName(), theClass);
+ }
+ String alias = theClass.getName();
+ int pos = alias.lastIndexOf(".");
+ if (pos != -1) {
+ alias = alias.substring(pos + 1);
+ }
+ obj = globalClassNameClassMap.get(alias);
+ if (obj == null) {
+ globalClassNameClassMap.put(alias, theClass);
+ }
+ if (Debug.verboseOn()) {
+ Debug.logVerbose("Registered class " + theClass.getName() + ", alias " + alias, module);
+ }
+ }
+ }
+
public CachedClassLoader(URL[] url, ClassLoader parent, String contextName) {
super(url, parent);
this.contextName = contextName;
@@ -162,44 +170,47 @@
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- //check glocal common classes, ie for all instances
+ //check global common classes, ie for all instances
Class<?> theClass = globalClassNameClassMap.get(name);
+ if (theClass != null) {
+ return theClass;
+ }
//check local classes, ie for this instance
- if (theClass == null) theClass = localClassNameClassMap.get(name);
+ theClass = this.localClassNameClassMap.get(name);
+ if (theClass != null) {
+ return theClass;
+ }
//make sure it is not a known bad class name
- if (theClass == null) {
- if (localBadClassNameSet.contains(name) || globalBadClassNameSet.contains(name)) {
- if (Debug.verboseOn()) Debug.logVerbose("Cached loader got a known bad class name: [" + name + "]", module);
- throw new ClassNotFoundException("Cached loader got a known bad class name: " + name);
- }
+ if (this.localBadClassNameSet.contains(name) || globalBadClassNameSet.contains(name)) {
+ if (Debug.verboseOn()) Debug.logVerbose("Cached loader got a known bad class name: [" + name + "]", module);
+ throw new ClassNotFoundException("Cached loader got a known bad class name: " + name);
}
- if (theClass == null) {
- if (Debug.verboseOn()) Debug.logVerbose("Cached loader cache miss for class name: [" + name + "]", module);
-
- synchronized (this) {
- theClass = localClassNameClassMap.get(name);
- if (theClass == null) {
- try {
- theClass = super.loadClass(name, resolve);
- if (isGlobalPath(name)) {
- globalClassNameClassMap.put(name, theClass);
- } else {
- localClassNameClassMap.put(name, theClass);
- }
- } catch (ClassNotFoundException e) {
- //Debug.logInfo(e, module);
- if (Debug.verboseOn()) Debug.logVerbose("Remembering invalid class name: [" + name + "]", module);
- if (isGlobalPath(name)) {
- globalBadClassNameSet.add(name);
- } else {
- localBadClassNameSet.add(name);
- }
- throw e;
+ if (Debug.verboseOn()) Debug.logVerbose("Cached loader cache miss for class name: [" + name + "]", module);
+
+ synchronized (this) {
+ try {
+ theClass = super.loadClass(name, resolve);
+ if (isGlobalPath(name)) {
+ synchronized (globalClassNameClassMap) {
+ globalClassNameClassMap.put(name, theClass);
+ }
+ } else {
+ this.localClassNameClassMap.put(name, theClass);
+ }
+ } catch (ClassNotFoundException e) {
+ //Debug.logInfo(e, module);
+ if (Debug.verboseOn()) Debug.logVerbose("Remembering invalid class name: [" + name + "]", module);
+ if (isGlobalPath(name)) {
+ synchronized (globalBadClassNameSet) {
+ globalBadClassNameSet.add(name);
}
+ } else {
+ this.localBadClassNameSet.add(name);
}
+ throw e;
}
}
return theClass;
@@ -207,43 +218,46 @@
@Override
public URL getResource(String name) {
- //check glocal common resources, ie for all instances
+ //check global common resources, ie for all instances
URL theResource = globalResourceMap.get(name);
+ if (theResource != null) {
+ return theResource;
+ }
//check local resources, ie for this instance
- if (theResource == null) theResource = localResourceMap.get(name);
-
- //make sure it is not a known bad resource name
- if (theResource == null) {
- if (localBadResourceNameSet.contains(name) || globalBadResourceNameSet.contains(name)) {
- if (Debug.verboseOn()) Debug.logVerbose("Cached loader got a known bad resource name: [" + name + "]", module);
- return null;
- }
+ theResource = this.localResourceMap.get(name);
+ if (theResource != null) {
+ return theResource;
}
- if (theResource == null) {
- if (Debug.verboseOn()) Debug.logVerbose("Cached loader cache miss for resource name: [" + name + "]", module);
- //Debug.logInfo("Cached loader cache miss for resource name: [" + name + "]", module);
-
- synchronized (this) {
- theResource = localResourceMap.get(name);
- if (theResource == null) {
- theResource = super.getResource(name);
- if (theResource == null) {
- if (Debug.verboseOn()) Debug.logVerbose("Remembering invalid resource name: [" + name + "]", module);
- //Debug.logInfo("Remembering invalid resource name: [" + name + "]", module);
- if (isGlobalPath(name)) {
- globalBadResourceNameSet.add(name);
- } else {
- localBadResourceNameSet.add(name);
- }
- } else {
- if (isGlobalPath(name)) {
- globalResourceMap.put(name, theResource);
- } else {
- localResourceMap.put(name, theResource);
- }
+ //make sure it is not a known bad resource name
+ if (localBadResourceNameSet.contains(name) || globalBadResourceNameSet.contains(name)) {
+ if (Debug.verboseOn()) Debug.logVerbose("Cached loader got a known bad resource name: [" + name + "]", module);
+ return null;
+ }
+
+ if (Debug.verboseOn()) Debug.logVerbose("Cached loader cache miss for resource name: [" + name + "]", module);
+ //Debug.logInfo("Cached loader cache miss for resource name: [" + name + "]", module);
+
+ synchronized (this) {
+ theResource = super.getResource(name);
+ if (theResource == null) {
+ if (Debug.verboseOn()) Debug.logVerbose("Remembering invalid resource name: [" + name + "]", module);
+ //Debug.logInfo("Remembering invalid resource name: [" + name + "]", module);
+ if (isGlobalPath(name)) {
+ synchronized (globalBadResourceNameSet) {
+ globalBadResourceNameSet.add(name);
+ }
+ } else {
+ this.localBadResourceNameSet.add(name);
+ }
+ } else {
+ if (isGlobalPath(name)) {
+ synchronized (globalBadResourceNameSet) {
+ globalResourceMap.put(name, theResource);
}
+ } else {
+ this.localResourceMap.put(name, theResource);
}
}
}
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java?rev=834727&r1=834726&r2=834727&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/CachedClassLoaderInit.java Wed Nov 11 00:39:44 2009
@@ -18,17 +18,12 @@
*/
package org.ofbiz.entity.util;
-import java.util.Map;
-
import org.ofbiz.base.util.CachedClassLoader;
public class CachedClassLoaderInit implements CachedClassLoader.Init {
- public void loadClasses(ClassLoader loader, Map<String, Class<?>> classNameMap) throws ClassNotFoundException {
- classNameMap.put("GenericValue", loader.loadClass("org.ofbiz.entity.GenericValue"));
- classNameMap.put("org.ofbiz.entity.GenericValue", loader.loadClass("org.ofbiz.entity.GenericValue"));
- classNameMap.put("GenericPK", loader.loadClass("org.ofbiz.entity.GenericPK"));
- classNameMap.put("org.ofbiz.entity.GenericPK", loader.loadClass("org.ofbiz.entity.GenericPK"));
- classNameMap.put("GenericEntity", loader.loadClass("org.ofbiz.entity.GenericEntity"));
- classNameMap.put("org.ofbiz.entity.GenericEntity", loader.loadClass("org.ofbiz.entity.GenericEntity"));
+ public void loadClasses(ClassLoader loader) throws ClassNotFoundException {
+ CachedClassLoader.registerClass(loader.loadClass("org.ofbiz.entity.GenericValue"));
+ CachedClassLoader.registerClass(loader.loadClass("org.ofbiz.entity.GenericPK"));
+ CachedClassLoader.registerClass(loader.loadClass("org.ofbiz.entity.GenericEntity"));
}
}