You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Carlos Pita <cp...@tycdigital.com> on 2001/03/15 09:49:40 UTC

Tomcat 3.2, RMI, JNDI & Classloaders: a solution

Hi all!

    A lot of people has been having problems with Tomcat 3.2, classloaders,
jndi, jndi.properties, rmi and stubs when trying to call ejbs from Tomcat in
a different JVM. The problem is simple: because jndi and rmi classes are
loaded by the system (or bootstrap, I can't remember it but it really
doesn't matters) classloader -see
<jdk1.3>\docs\tooldocs\findingclasses.html - they can not see the resources
and classes of your context (loaded by the context classloader, which is a
descendant -i mean in the classloader delegation hierarchy- of the system
classloader).
    An obvious and bad solution is to put your classes in the CLASSPATH
(don't do this!) to allow them to be loaded once for all of your contexts by
the system classloader.
    Instead, to fix the problem you should add the request interceptor
showed below to your server.xml (I have read an email saying that it should
be the last request interceptor in the chain so I put it the last, but I
haven't tried with another combinations):

        <RequestInterceptor
             className="org.apache.tomcat.request.Jdk12Interceptor" />

    This is in order to call the Thread.setContextClassLoader() during each
request. The following is taken from a post by C. McClanahan in tomcat-user:
"Note that Tomcat 4.0, because it is guaranteed a Java2 platform as a
prerequisite, calls Thread.setContextClassLoader() on every request by
default".
    But even after doing this, jndi.properties in your WEB-INF/classes (or
in a .jar in WEB-INF/lib) won't be loaded. Keep reading the following
paragraphs quoted from an email by Christopher Audley in tomcat-dev!

""
The following discussion applies to tomcat 3.2.1 running under Sun JDK 1.3

I spent this afternoon tracking down why a call to new InitialContext()
from a web application did not appear to be finding the jndi.properties
located under WEB-INF/classes.  I am using the Jdk12Interceptor and
verified that Thread.currentThread().getClassLoader() was the tomcat
AdaptiveClassLoader before the call to new InitialContext().  After some
investigation I determined that the JNDI implementation uses the
classloader method getResources to find all occurances of the file
jndi.properties in the classpath.  AdaptiveClassLoader does not have
this method implemented, the default implementation calls findResources
which simply returns an empty Enumeration unless overriden.

Attached are patches to AdaptiveClassLoader and ClassRepository to
implement findResources so that JNDI will behave correctly when a
jndi.properties is placed in the web application classpath.  I have
moved some code from AdaptiveClassLoader to ClassRepository to avoid
code duplication and changed the implementation of getResource to
findResource for consistency.

I hope that this can be incorporated into the sources before 3.2.2.
""

    Finally, after aplying the patch (I've attached it as you can see) and
recompiling the sources you get the desired behaviour.

See you,
    Carlos