On Fri, 17 Aug 2001, Paresh Deshpande wrote:

> Hi Rob, 
> thanks for your reply, Rob. I was waiting for the reply for quite a while
> :)).
> It is not specifically mentioned in the docs how the class files in
> WEB-INF\classes
> are loaded. Neither is it mentioned whether the jar file in the
> WEB-APP\lib folder will be automatically picked in classpath. 

Technically, Tomcat does not modify the CLASSPATH *environment variable*,
but it does make these classes available to your application.  If you
think about it for a second, this makes sense -- different web apps have
different sets of classes available, but there is only one CLASSPATH ...

> If I do not provide anything (jar or WEB-INF\classes) from my web
> application folder,
> kind of strange problem occurs in which the servlets get loaded from
> WEB-INF\classes
> directory, but when I try to cast a particular resource from JNDI to my
> class (
> placed in the same WEB-INF\classes folder), I get class cast exception
> error. Tomcat 
> does not find the class. How can I solve this problem?
> paresh
> 

A likely cause of this problem is the following (which is why class
loaders are black magic sometimes :-).

When Tomcat starts up, it creates a hierarchy of class loaders.  Here's a
simplified model for Tomcat 3.2.x:

    Java Runtime Classes
        |
    System Extensions Classloader ($JAVA_HOME/jre/lib/ext/*.jar)\
        |
    System Classloader ($CLASSPATH)
        |
    Webapp Classloader (/WEB-INF/classes, /WEB-INF/lib/*.jar)

Now, when you try to create a class in a servlet (i.e. Object foo = new
Foo()), you are asking the webapp class loader to load class Foo.  If it's
there, that's fine and dandy ... if not, it delegates upwards to see if
one of the parent class loaders can find it.  (That is why classes you put
on the classpath are visible to all webapps in 3.2).

But note -- the searching process only goes *upwards*, not
*downwards*.  In other words, a class that is loaded from the System
Classloader (for example) cannot see *any* classes in the webapp class
loader.

Why does this matter to you?  Because the key to your problem is most
likely where the JNDI classes themselves are being loaded from.  If you
have jndi.jar on your CLASSPATH, they are being loaded from the System
Classloader.  If you're running JDK 1.3 or above, they are loaded from the
Java Runtime Classes classloade.  But, you're trying to reference a class
that is loaded from your webapp classloader.  Can you see the problem yet?

A couple of approaches to try:

* Move the JNDI classes into your webapp (in /WEB-INF/lib).  This won't
  work on a JDK 1.3 or above system, though.

* Move the application classes you want to cast to up into
  the System classloader (by putting them on the CLASSPATH, or
  into Tomcat's top level "lib" directory).

Craig

Reply via email to