Return-Path: Delivered-To: apmail-xml-cocoon-dev-archive@xml.apache.org Received: (qmail 10212 invoked by uid 500); 31 May 2002 07:59:44 -0000 Mailing-List: contact cocoon-dev-help@xml.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: cocoon-dev@xml.apache.org Delivered-To: mailing list cocoon-dev@xml.apache.org Received: (qmail 10195 invoked from network); 31 May 2002 07:59:44 -0000 Subject: [Proposal] Cocoon's RepositoryClassLoader From: David Haraburda To: cocoon-dev@xml.apache.org Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Mailer: Ximian Evolution 1.0.5 Date: 31 May 2002 02:58:23 -0500 Message-Id: <1022831903.24699.63.camel@inspiron> Mime-Version: 1.0 X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Hi, After spending several days mulling over a problem with JNDI and Tomcat and Cocoon, I am writing to suggest that Cocoon's class loading mechanism be looked at and perhaps re-thought. I'll jump right in and describe why I think changes should be made to Cocoon, and I'll include a description of the problem I encountered at the end for those interested. Cocoon is attaching its RepositoryClassLoader to each Thread instance as its context ClassLoader, inappropriately I believe. The J2SE API Docs state that java.lang.Thread's setContextClassLoader(...) method.. "Sets the context ClassLoader for this Thread. The context ClassLoader can be set when a thread is created, and allows the creator of the thread to provide the appropriate class loader to code running in the thread when loading classes and resources." Although not explicitly describing a restriction, this implies that it is the Thread's creator's responsibility to set the Context ClassLoader. If this is true, then this responsibility should be left to the servlet container (Tomcat in my case, which does set the Context ClassLoader). Tomcat has to do this, because the J2EE specification (v 1.3) requires "...that J2EE containers provide a per thread context class loader for the use of system or library classes in dynamicly loading classes provided by the application" (section 6.2.4.8) The spec goes on to state that the reason for this is that classes loaded by lower class loaders in the hierarchy need to be able to discover the "top-level application" class loader. Obviously, if Cocoon sets the Context ClassLoader, this causes a problem. It could be that I am completely confused :-) but looking at the code, I am not sure I understand why Cocoon subclasses URLClassLoader. The javadoc says that RepositoryClassLoader is "a class loader with a growable list of path search directories" -- and it provides public methods that call URLClassLoader's protected addURL(...) method. I don't understand why there is a need to modify the "class path" of a class loader, once it has been initialized -- the few places I've seen Cocoon use addDirectory(...) could easily be changed to properly support using the servlet container's ClassLoader. Also, as a side note, I took note of the fact that there is an init-classloader parameter in Cocoon's web.xml, which is supposed to (I assume) turn off the use of RepositoryClassLoader -- but in CocoonServlet's service method, this parameter is ignored, and RepositoryClassLoader is set as the context class loader with the comment: /* HACK for reducing class loader problems. */ /* example: xalan extensions fail if someone adds xalan jars in tomcat3.2.1/lib */ I am curious as to what kind of problems have been encountered without setting this? (users really shouldn't be adding jars to TOMCAT_HOME/lib anyway) As far as I can see, RepositoryClassLoader builds its own classpath "by hand" if you will -- actually doing work that is the servlet container's job (and that has already been done) I am ready and willing to submit a patch, if I can get some feedback from Cocoon developers -- mostly, I am wondering what kind of weird ClassLoader issues were there that inspired the creation of RepositoryClassLoader? :-) Finally, I apologize for the length of my e-mail, and for most likely being really confused (it is late). Here is a description of my problem for those interested: I am running Cocoon 2.0.2 on Tomcat 4.0.x (I'm currently using 4.0.4 beta 3, but its a problem on all 4.0.x releases). I have enlisted an object in the JNDI namespace by configuring Tomcat to do so (in server.xml and Cocoon web.xml). Each web application has it's own Environment Naming Context, which is linked to the web applications class loader (each web application gets its own WebAppClassLoader, provided by Tomcat). The problem comes in when Cocoon sets up its own ClassLoader. This causes JNDI lookups (and other operations) to fail because there is no link between the ENC setup for the webapp and Cocoon's ClassLoader. I submitted a patch to Tomcat to correct this problem, and it was applied to the 4.1.x codebase, but I agree with the Tomcat developer who committed my patch in thinking that this is more a problem with Cocoon than it is Tomcat -- thus why I make the proposal above. Thanks, David --------------------------------------------------------------------- To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org For additional commands, email: cocoon-dev-help@xml.apache.org