commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Howard M. Lewis Ship" <hls...@comcast.net>
Subject RE: [HiveMind] Having problem with tomcat.
Date Wed, 10 Sep 2003 20:39:40 GMT
I just adapted your patch and checked in the result; I made minor changes (each module will
get its
own ClassFactoryClassLoader, which is overkill when multiple modules share the same class
loader ...
I just wasn't comfortable using IdentityHashMap keyed on ClassLoader).  All my tests pass.
 Please
retry using your environment, thanks!

--
Howard M. Lewis Ship
Creator, Tapestry: Java Web Components
http://jakarta.apache.org/tapestry
http://jakarta.apache.org/commons/sandbox/hivemind/
http://javatapestry.blogspot.com

> -----Original Message-----
> From: Essl Christian [mailto:jucas@esslchristian.de] 
> Sent: Wednesday, September 10, 2003 2:22 PM
> To: Jakarta Commons Developers List
> Subject: Re: [HiveMind] Having problem with tomcat.
> 
> 
> 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/ClassFabIm
> pl.java	30 
> Aug 2003 14:29:54 -0000	1.8
> +++ 
> src/java/org/apache/commons/hivemind/service/impl/ClassFabIm
> pl.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/ClassFactory
> Impl.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/ClassFactory
> Impl.java	10 
> Sep 2003 15:00:47 -0000	1.8
> +++ 
> src/java/org/apache/commons/hivemind/service/impl/ClassFactory
> Impl.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;
> +		}
> +	}
> +	
>  }
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


Mime
View raw message