Arthur Ash wrote:
> Hi Folks,
>
> I'm having a general issue with the app-specific classpath (WEB-INF/classes
> and WEB-INF/lib/*.jar).
>
> Here is the scenario as I understand it:
> I have an MVC servlet/bean framework that is installed in the primordial
> classpath. It contains a single dispatcher servlet which instantiates
> handler classes (which function like servlets) using Class.forName(). My
> intention is to to put these app-specific handler classes in
> WEB-INF/classes or WEB-INF/lib in order to be a good J2EE citizen.
>
The Struts framework <http://jakarta.apache.org/struts> follows essentially the
same model. However, due to classloader issues (more discussion below) the
controller servlet class itself must also be in WEB-INF/classes or WEB-INF/lib
for this to work correctly.
>
> However, since the dispatch servlet has been loaded with the primordial
> class loader (ie, the Tomcat code first tried and succeeded to load it
> using the default class loader), when it itslef calls Class.forName(), it
> gets this same (primordial) ClassLoader. It cannot see anything that is in
> WEB-INF, since this is visible to only to the servlet class loader (ie,
> com.apache.tomcat.loader.AdaptiveClassLoader).
>
Class loaders are arranged in a hierarchy. For Tomcat 4.0, the details are
discussed in a developer document ("catalina/docs/dev/classloaders.html) in the
source tree. I will use that to illustrate what's going on because I'm more
familiar with it - Tomcat 3.2 currently follows a simplified version of the
same basic idea.
Bootstrap
|
System
|
Common
/ \
Catalina Shared
/ \
Webapp1 Webapp2 ...
Each class loader has a reference to its parent, but not to its children. So,
when your controller servlet is initially loaded (from a shared library
directory), what actually happened is:
* Java asked the webapp class loader to find the
controller servlet class
* The webapp class loader did not find the class
so it delegated to the shared class loader
* The shared class loader (which reads from $CATALINA_HOME/lib
in Tomcat 4.0 -- the corresponding loader in Tomcat 3.2 reads
from the system classpath) and finds your class
Now, when your controller servlet calls Class.forName(), it starts from its
*own* class loader, and looks either there, or upwards. Of course, if your
components are under WEB-INF/classes or WEB-INF/lib, they are not visible ...
>
> Am I just screwed or is there some cool trick that I am missing? Of course
> I could change the deployment scheme to put a copy of the dispatcher
> servlet into each apps WE-INF/classes, but this seems a bit clunky.
>
It's not clunky -- its required by virtue of the fact that classloaders know
how to delegate upwards but not downwards. For lots of security related
reasons, that is actually a Good Thing.
>
> thanks
> Arthur
>
Craig McClanahan
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]