Mark,

 

Thanks for your patch ! Unfortunately I don't think there is an easy
solution for doing what you're suggesting. We're trying to break the
J2EE model and I don't believe you'll succeed in a consistent way (i.e.
it may work on one server but will fail on another). The classloaders
are hierarchical (webappclassloader -> ejbclassloader -> system
classloader). Thus the problem is if you put a class in a parent class
loader that needs to call a child class loader, it will fail. You'll
have to move the called classloader to the parent.

 

Thus I believe there are only 2 valid configurations :

1/ All classes/jars outside WEB-INF/lib and in your system classpath
(yuck !)

2/ All needed classes/jars in WEB-INF/lib and WEB-INF/classes (The Way
to go)

 

This is done voluntarily by the J2EE spec. (although it could be viewed
as a limitation and future spec may remove it). This is to compartiment
webapps so that they live in their own space. Thus, for example, you can
dynamically reload a webapp without impacting the others. Same for EARs.

 

If you need more convincing (;-)) here is an email posted by Craig (he
is an authority when it comes to Tomcat . among other things) :

 

"Roytman, Alex" wrote:
 
> I would like to use Thread.currentThread().getContextClassLoader()
with
> Tomcat 3.2 to resolve one common problem when class from system
classpath
> needs to call something loaded by tomcat context's loader. As far as I
> understand Tomcat 3.2 suppose to run under jdk1.1 so it does not do
> Thread.currentThread().setContextClassLoader() before it hands control
to a
> Servlet.
>
 
If Tomcat 3.2 runs in a Java2 environment, it does in fact call
setContextClassLoader(), assigning the webapp class loader for the
currently
selected web application to the current request thread.  Tomcat 4.0 does
this
under all circumstances, because it requires a Java2 environment.
However, the
fact that this occurs has nothing to do with your issue.
 
Under any version of Tomcat, what you are asking for does not work.
More
importantly, it *should not* work.  Class loaders are only allowed to
look *up*
the class loader hierarchy (and, of course, such a hierarchy exists only
in a
Java2 environment).  Classes that are loaded from the system class path
*do not*
have any access to classes loaded only by a webapp's class loader.  If
they did,
it would violate the whole concept of a web application being self
contained.
 
If you have a class that needs access to classes that are loaded from
WEB-INF/classes and WEB-INF/lib, that class itself must be loaded from
one of
those two places (and therefore loaded by the webapp class loader).
 
Craig McClanahan
 
 

For these reasons, I'm not too keen to include your patch for the
above-mentionned reasons.

 

Note: Be careful about what container classloader report as error. They
will report thing such as cannot load class A but in fact the error is
because they browsed the dependency tree and couldn't load a class that
is called by one of the descendant of the initial class .

 

Thanks

-Vincent

 

-----Original Message-----
From: Volkmann, Mark [mailto:[EMAIL PROTECTED]] 
Sent: 21 February 2002 14:12
To: 'Fred Loney'; '[EMAIL PROTECTED]'
Subject: RE: java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCase

 

We did resolve the problem, but the solution isn't pretty. We had to
patch Cactus to get it to work. I've attached a class we added. We
replaced all calls to Class.forName in the Cactus source with calls to
ClassLoaderHelper.forName. This allows classes in your web app., such as
your unit test code, to find classes in your server classpath, such as
Cactus and Log4J classes. We think the problem has something to do with
using Log4J in our application. We put log4j.jar in our server classpath
and this seems to be a problem for Cactus without the patch. I've also
attached our custom cactus.jar file that contains these changes.

All you need to do to try it is put all the JARs cactus needs
(aspectjrt.jar, cactus.jar, httpunit.jar, junit.jar and log4j.jar) in
your server classpath instead of your web app. Another advantage to this
approach is that you don't have to include all those JARs in every web
application. That's a big plus for us because we are testing around 20
web apps. Perhaps this change should become part of the normal Cactus
codebase!

If this is a bad idea, I'd like to hear why. 

<<ClassLoaderHelper.java>> <<cactus.jar>> 

-----Original Message----- 
From:   Fred Loney [SMTP:[EMAIL PROTECTED]] 
Sent:   Wednesday, February 20, 2002 9:23 PM 
To:     Volkmann, Mark 
Subject:        java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCase 

Were you able to resolve the problem? I have the same situation and 
would appreciate any advice on resolution. Classloaders are truly the 
bane of webapp development. 

Thanks. 

---- 
Mark Volkmann wrote: 

Here's part of the stack trace I'm getting. 
cactus.jar, junit.jar and aspectjrt.jar are in the WEB-INF/lib of the 
WAR 
file of my web application. 
They are not available through my CLASSPATH. 
How could it find AbstractTestCaller, but not find ServletTestCase? 

java.lang.NoClassDefFoundError: org/apache/cactus/ServletTestCase 
at java.lang.ClassLoader.defineClass0(Native Method) 
at java.lang.ClassLoader.defineClass(ClassLoader.java:486) 
at 
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111) 
at 
weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericCla

ssLo 
ader.java:339) 
at 
weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoa

der. 
java:156) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:297) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:290) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:253) 
at 
weblogic.utils.classloaders.ChangeAwareClassLoader.loadClass(ChangeAware

Clas 
sLoader.java:43) 
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313) 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Class.java:120) 
at 
org.apache.cactus.server.AbstractTestCaller.getTestClassClass(AbstractTe

stCa 
ller.java:326) 

 



************************************************************************
***************
WARNING: All e-mail sent to and from this address will be received or
otherwise recorded by the A.G. Edwards corporate e-mail system and is
subject to archival, monitoring or review by, and/or disclosure to,
someone other than the recipient.
************************************************************************
***************

Reply via email to