commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Essl Christian <ju...@esslchristian.de>
Subject Re: [HiveMind] Having problem with tomcat.
Date Wed, 10 Sep 2003 18:22:11 GMT
On Wed, 10 Sep 2003 11:01:12 -0400, Howard M. Lewis Ship 
<hlship@comcast.net> wrote:

> I just checked in a tiny change to ClassFactoryImpl that may (but 
> probably won't) fix your problem.
> Please give it a try.
>

Unfortunately this didn't work either.

However I found a way. I think the problem is that HiveMind uses 
ClassPool.writeAsClass() to obtain the Class.
This inturn uses an internal ClassLoader which is a child of the 
SystemClassLoader only. The internal classloader
is needed to load classes on which the new Class depends (in Hivemind 
typically interfaces). As in any Servelt-Container the ServicesInterfaces 
are not contained in the SystemClassLoader the Interfaces can not be found.

Therefore I make a new ClassLoader for each used ClassLoader in the Modules 
and give this to the ClassFabImpl. The
ClassFabImpl than creates with this classLoader the class [ 
_classLoader.loadClass(_ctClass.getName(), _pool.write(_ctClass.getName())) 
; ]

This works fine now.

The diff is:


Index: src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons- 
sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java,v
retrieving revision 1.8
diff -u -r1.8 ClassFabImpl.java
--- src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java	30 
Aug 2003 14:29:54 -0000	1.8
+++ src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java	10 
Sep 2003 18:16:24 -0000
@@ -86,14 +86,17 @@
     private ClassFactoryImpl _factory;
     private CtClass _ctClass;
     private ClassPool _pool;
+    //used in create Class
+    private ClassFactoryImpl.LocalClassLoader _classLoader;
 private static final boolean WRITE_CLASS = 
Boolean.getBoolean("hivemind.write-class");
 -    public ClassFabImpl(ClassFactoryImpl factory, CtClass ctClass)
+    public ClassFabImpl(ClassFactoryImpl factory, CtClass ctClass, 
ClassFactoryImpl.LocalClassLoader cL)
     {
         _factory = factory;
         _ctClass = ctClass;
         _pool = ctClass.getClassPool();
+        _classLoader = cL;
     }
 public void addInterface(Class interfaceClass)
@@ -213,8 +216,12 @@
         {
             if (WRITE_CLASS)
                 _ctClass.writeFile();
-
-            return _pool.writeAsClass(_ctClass.getName());
+			
+			//use now our classLoader which is a child of the module ClassLoader
+			//instead of (implicitly) the ClassPool.LocalClassLoader, (which is 
always a child of +			//the SystemClassLoader) through _pool.writeAsClass() 
.
+            Class ret = _classLoader.loadClass(_ctClass.getName(), 
_pool.write(_ctClass.getName()));
+            return ret;
         }
         catch (Exception ex)
         {
@@ -226,5 +233,6 @@
                 ex);
         }
     }
-
+	
+	
 }
Index: 
src/java/org/apache/commons/hivemind/service/impl/ClassFactoryImpl.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons- 
sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFactoryImpl.java,v
retrieving revision 1.8
diff -u -r1.8 ClassFactoryImpl.java
--- 
src/java/org/apache/commons/hivemind/service/impl/ClassFactoryImpl.java	10 
Sep 2003 15:00:47 -0000	1.8
+++ 
src/java/org/apache/commons/hivemind/service/impl/ClassFactoryImpl.java	10 
Sep 2003 18:16:26 -0000
@@ -58,6 +58,7 @@
 package org.apache.commons.hivemind.service.impl;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.Map;
 import javassist.ClassPath;
@@ -87,6 +88,12 @@
      * Map of ClassPool, keyed on module id.
      */
     private Map _poolMap = new HashMap();
+    +    /**
+     * maps ClassLoaders of ClassResolvers (key) to LocalClassLoaders (JRE 
1.4)
+     */
+    private IdentityHashMap _localClassLoaders = new IdentityHashMap();
+
 public ClassFab newClass(String name, Class superClass, Module module)
     {
@@ -94,11 +101,13 @@
 CtClass ctSuperClass = getClass(pool, superClass);
 +		LocalClassLoader classLoader = findLocalClassLoader(module);
+		
         try
         {
             CtClass ctNewClass = pool.makeClass(name, ctSuperClass);
 -            return new ClassFabImpl(this, ctNewClass);
+            return new ClassFabImpl(this, ctNewClass,classLoader);
         }
         catch (Exception ex)
         {
@@ -149,5 +158,48 @@
 return result;
     }
+    +	/**
+	 * finds and creates LocalClassLoader for each ClassLoader used in 
ClassResolver
+	 * @param module
+	 * @return LocalClassLoader
+	 */
+	private synchronized LocalClassLoader findLocalClassLoader(Module module)
+	{
+		
+		ClassLoader resCL = module.getClassResolver().getClassLoader();
+		LocalClassLoader ret = (LocalClassLoader) 
this._localClassLoaders.get(resCL);
+		if(ret == null){
+			ret = new LocalClassLoader(resCL);
+			this._localClassLoaders.put(resCL,ret);
+		}
+		
+		return ret;
+	}
+    +	/**
+	 * ClassLoader which does not directly go into the SystemClassLoader as 
the one
+	 * used by ClassPool internally. Rather it uses to lookup dependend 
classes the
+	 * ClassLoader from the ClassResolver. (Only the constructor is changed 
from
+	 * ClassPool.LocalClassLoader)
+	 * +	 * Created 10.09.2003
+	 * @author chris
+	 *
+	 */
+	static class LocalClassLoader extends ClassLoader {
+		public LocalClassLoader(ClassLoader parent){
+			super(parent);
+		}
+		
+		public Class loadClass(String name, byte[] classfile)
+			throws ClassFormatError
+		{
+			Class c = defineClass(name, classfile, 0, classfile.length);
+			resolveClass(c);
+			return c;
+		}
+	}
+	
 }



Mime
View raw message