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]>

Reply via email to