Hi, I believe I have found a bug (or a problem at least) with the way Tomcat handles associating webapp contexts to JNDI naming contexts.
ContextBindings.java, which apparently handles these associations does not account for the fact that a web application may have its own ClassLoader. I am trying to use Apache Cocoon which does this. I've properly enlisted the object I want in the namespace using the server.xml file and the web.xml file. After Tomcat creates this NamingContext, it "binds" it to Cocoon's context in ContextBindings.java, using the current ClassLoader as a key, which happens to be Tomcat's WebAppClassLoader. Cocoon provides its own ClassLoader (because it is a rather complex beast :-), so when I try to get to my object in the namespace it can't be found (even though its parent ClassLoader is the correct WebAppClassLoader) This may or may not be appropriate, but I've found that it works for me. I've modified the following methods in ContextBindings.java: getClassLoader() getClassLoaderName() isClassLoaderBound() so that they check the hashtable for the current ClassLoader, and continue to search up the heirarchy by looking at that ClassLoader's parent -- returning success at the first match, and returning failure once it has been all the way up the heirarchy. A method I did not modify was unbindClassLoader() -- I'll leave that to further discussion because (if my solution is acceptable) I'm not sure if it is appropriate to leave it or change it. This patch is against CVS revision 1.4 of the file, which I got from the source distribution of Tomcat 4.0.4 beta 3. Hope this helps others with the same problem. Thanks, David Haraburda
--- ContextBindings.java Fri May 10 21:30:30 2002 +++ ContextBindings.dharaburda.java Tue May 28 02:38:28 2002 @@ -345,12 +345,14 @@ */ public static Context getClassLoader() throws NamingException { - Context context = (Context) clBindings.get - (Thread.currentThread().getContextClassLoader()); - if (context == null) + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Context context = null; + do { + context = (Context) clBindings.get(cl); + if( context != null ) return context; + } while( (cl = cl.getParent()) != null ); throw new NamingException (sm.getString("contextBindings.noContextBoundToCL")); - return context; } @@ -359,12 +361,14 @@ */ static Object getClassLoaderName() throws NamingException { - Object name = - clNameBindings.get(Thread.currentThread().getContextClassLoader()); - if (name == null) + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Object name = null; + do { + name = clNameBindings.get(cl); + if( name != null ) return name; + } while( (cl = cl.getParent()) != null ); throw new NamingException (sm.getString("contextBindings.noContextBoundToCL")); - return name; } @@ -372,8 +376,11 @@ * Tests if current class loader is bound to a context. */ public static boolean isClassLoaderBound() { - return (clBindings.containsKey - (Thread.currentThread().getContextClassLoader())); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + do { + if( clBindings.containsKey(cl) ) return true; + } while( (cl = cl.getParent()) != null ); + return false; }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>