tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Vincent Massol" <vmas...@octo.com>
Subject Re: WebappClassLoader question
Date Thu, 26 Jul 2001 16:16:24 GMT
Thanks Alex,

I don't think the standard classloader mechanism is involved here. I believe
it is a 'feature' of Tomcat and more specifically of it's WebappClassLoader.
When you do standard java code and you have the following situation :

1st -> 2nd --- (using reflection) --> 3rd (not in classpath)

then the error always happen in the 2nd class and you can put the code
between a try catch block and you'll be able to catch the
ClassNotFoundException. However what happens here is that the error happens
when calling a method on the 1st class that instanciates the 2nd class !
This is what I don't understand.

Am I dreaming or is this a behaviour of Tomcat 4 ?

Thanks
-Vincent

----- Original Message -----
From: "Alex Fernández" <afm229@tid.es>
To: <tomcat-user@jakarta.apache.org>
Sent: Wednesday, July 25, 2001 3:44 PM
Subject: Re: WebappClassLoader question


> Hi Vincent!
>
> I've run into the same situation a couple of times, when one class uses
> a second class, and this second class uses a third one that is not
> present.
>
> 1st -> 2nd -> 3rd (missing)
>
> One would think that instantiating the 2nd should give an error, but
> that loading the 2nd and/or instantiating the 1st should be ok. In fact,
> all of the behaviors raise exceptions.
>
> The following paragraph in ClassLoader javadoc might be of help:
>
> "The methods and constructors of objects created by a class loader may
> reference other classes. To determine the class(es) referred to, the
> Java virtual machine calls the loadClass method of the class loader that
> originally created the class."
>
> Or, to find out what the JVM is doing, the spec is here:
> http://java.sun.com/docs/books/vmspec/
>
> Hope it helps.
>
> Un saludo,
>
> Alex.
>
> > Vincent Massol wrote:
> >
> > Hi,
> >
> > Here is the situation :
> >
> > * I have a class that makes use of JUnit (by extending the JUnit
> > TestCase class). Let's call it ServletTestCase
> > * I have a second class that is used to call a method in
> > ServletTestCase, let's call it MyProxyClass
> > * I have a third class (a servlet) that does _not_ make use of JUnit.
> > Let's call it ServletTestRedirector. This class actually instanciate
> > MyProxyClass and calls one of its method.
> > * I package these classes in a war file and I _don't_ include
> > junit.jar in this war file
> >
> > When I access the servlet, I get a ClassNotFoundException on a JUnit
> > class. So far it is normal ...
> > When I debugged it, I have actually found that the error was happening
> > when ServletTestRedirector was instancianting MyProxyClass (which does
> > _not_ make use of JUnit) and before it was calling its method.
> >
> > Here is the stack trace I got :
> >
> > java.lang.NoClassDefFoundError: junit/framework/TestCase
> >  at java.lang.ClassLoader.defineClass0(Native Method)
> >  at java.lang.ClassLoader.defineClass(ClassLoader.java:486)
> >  at
> > java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111)
> >  at
> >
org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLo
ader.java:1475)
> >  at
> >
org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.jav
a:836)
> >  at
> >
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.jav
a:1215)
> >  at
> >
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.jav
a:1098)
> >  at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
> >  at
> >
org.apache.commons.cactus.server.ServletTestRedirector.doPost(ServletTestRed
irector.java:143)
> > Here is what I imagined is happening (tell me if this correct or wrong
> > !) :
> >
> > As MyProxyClass is within the war file, the WebappClassLoader gets
> > called to load it. The WebappClassLoader, in trying to find out the
> > correct class, actually loads some other class in memory, and thus the
> > ServletTestCase, which fails to load because the junit jar is not in
> > the classpath.
> >
> > Is that correct ?
> > Don't you find it strange that the error about the missing class is
> > reported when calling a class that has nothing to do with the problem
> > ? It gets very hard to catch errors ...
> >
> > For example, in MyProxyClass, the code that calls the ServletTestCase
> > method is as follows :
> >
> >         ServletTestCase testInstance = null;
> >         try {
> >             testClass = Class.forName(theClassName);
> >             Constructor constructor = testClass.getConstructor(new
> > Class[] { String.class });
> >             testInstance =
> > (ServletTestCase)constructor.newInstance(new Object[] { theMethod });
> >         } catch (Exception e) {
> >             logger.debug("Error instanciating class [" + theClassName
> > + "]", e);
> >             e.printStackTrace();
> >             throw new ServletException("Error instanciating class [" +
> > theClassName + "]", e);
> >         }
> > And there is never any exception caught here .... because the error
> > happens earlier in the call stack, when the ServletTestRedirector
> > instanciates MyProxyClass ...
> >
> > ... or am I missing something ? :)
> >
> > Thanks
> > -Vincent Massol
> >
>


Mime
View raw message