|Subject:||Re: Classloading question|
|From:||Craig R. McClanahan (crai...@apache.org)|
|Date:||Dec 21, 2002 10:49:10 am|
On Fri, 20 Dec 2002, Madere, Colin wrote:
Date: Fri, 20 Dec 2002 18:11:22 -0600 From: "Madere, Colin" <coli...@ieminc.com> Reply-To: Tomcat Users List <tomc...@jakarta.apache.org> To: 'Tomcat Users List' <tomc...@jakarta.apache.org> Subject: Classloading question
I put a jar in <tomcat home>/common/lib/ that has some base servlet classes I wrote. When writing apps, I derive from these classes. Works fine.
I put the velocity.jar file in the WEB-INF/lib folder of each app for using the "singleton" model of Velocity (jakarta.apache.org/velocity) so that each web app has it's own engine instance. Works fine.
I try to combine the two above by putting my base class jar in the /common/lib/ which has classes derived from the velocity.jar at the app level and I get a class loading error since apparently classes defined at the container level do not look in the /WEB-INF/lib for classes. If I put the base class jar that's in /common/lib/ in WEB-INF/lib it works, but I shouldn't have to do that. And the reverse also works (putting the velocity jar in the /common/lib/), but breaks the idea of the Velocity singleton model since all apps on the server will be sharing the same velocity engine and therefore all velocity-related resources (template location, log location, etc).
Is there any way out of having to copy my base class jar into every web app?
The fundamental rule of Java class loaders is that they look *up* the class loader hierarchy, not down (where the primoridial bootstrap class loader of the JVM is considered to be at the top of the tree).
The consequence of this is that, when your classes have dependencies on each other, the class being depended on must be loaded from the same class loader as the dependent class, or from a class loader higher than the one loading the dependent class.
In Tomcat terms, for example, that means it's illegal to have a dependent class loaded from common/lib/ that depends on a class loaded from /WEB-INF/lib, although the opposite arrangement is legal.
Regarding Velocity in particular, I'm sure you've noticed that static variables declared in a class that's loaded from common/lib are global to all webapps. It's possible for class libraries to program around that by cleverly using the "context class loader" provided by the app server (i.e. Tomcat makes the webapp class loader available while you're processing a request via Thread.currentThread().getContextClassLoader()), but this must be done deliberately by the class library author. It sounds like you might want to suggest this to the Velocity developers, so that you can put velocity.jar in common/lib but still have per-webapp resource definitions.