You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-dev@jakarta.apache.org by Nicholas Lesiecki <ni...@eblox.com> on 2002/02/21 20:17:55 UTC

RE: java.lang.NoClassDefFoundError: org/apache/cactus/ServletTestCase

RE: java.lang.NoClassDefFoundError: org/apache/cactus/ServletTestCaseMark,

Thank you for this submission. Essentially, I'd like to integrate your
change and then re-run the unit tests against several containers (Tomcat,
Resin, Orion, etc.) to make sure that it has no unintended consequences for
the "standard" configuration.

Off hand, I think your patch will make cactus configuration substantially
more forgiving. I'm looking forward to using it myself :)

As background to this change, interested developers should check out:

http://www.javageeks.com/Papers/ClassForName/index.html

(a paper by Ted Neward explaining the subtleties in the Java classloader
model: a worthwhile read for anyone doing web app development).

Thanks for contributing!

Cheers,

Nicholas Lesiecki
  -----Original Message-----
  From: Volkmann, Mark [mailto:Mark.Volkmann@AGEDWARDS.com]
  Sent: Thursday, February 21, 2002 7:12 AM
  To: 'Fred Loney'; 'cactus-user@jakarta.apache.org'
  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:loney@spiritedsw.com]
    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.

****************************************************************************
***********


Re: java.lang.NoClassDefFoundError: org/apache/cactus/ServletTestCase

Posted by Fred Loney <lo...@spiritedsw.com>.
RE: java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCaseNicholas and Mark,

Thanks to you both for your astute observations. Unfortunately,
recompiling with the patch and promoting the cactus dependent jars to
the system app classloader didn't resolve the problem for my particular
JBoss/Jetty configuration. JBoss, Jetty and junit each have their own
classloaders and I suspect that not all of them conform to the Java2
classloader javadoc recommended behavior.

I isolated the problem to a ServletTestCase subclass packaged at the ear
lib level rather than the war. The ear libs are referenced in the ejb
jar manifest classpath, and thus placed by the ejb container in a common
ear classloader that is the parent of the servlet container war
classloader. cactus.jar and junit.jar were not accessible when placed in
either the war lib or the system classpath.

When placed in the JBoss container classpath, cactus could not access
the javax.servlet class and raised yet another ClassDefNotFound. That is
because the JBoss classpath jars are apparently loaded by a parent of
the JBoss config jar classloader, where all significant J2EE jars
reside. Furthermore, log4j cannot be moved to the parent classloader
without causing a JBoss startup exception. I didn't try the extension
classloader, but I suspect that any work-around will merely push the
problem to another place.

The solution was to ensure that all ServletTestCase subclasses are in
the war classes or a war lib rather than a common ear lib.

Thanks again for the advice, which pointed me in the right direction. I
now know far more than I ever wanted to about classloaders.

Fred Loney
Spirited Software, Inc.
www.spiritedsw.com

----- Original Message -----
From: Nicholas Lesiecki
To: Cactus Users List ; 'Fred Loney'
Cc: Cactus Dev List
Sent: Thursday, February 21, 2002 11:17 AM
Subject: RE: java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCase


Mark,

Thank you for this submission. Essentially, I'd like to integrate your
change and then re-run the unit tests against several containers
(Tomcat, Resin, Orion, etc.) to make sure that it has no unintended
consequences for the "standard" configuration.

Off hand, I think your patch will make cactus configuration
substantially more forgiving. I'm looking forward to using it myself :)

As background to this change, interested developers should check out:

http://www.javageeks.com/Papers/ClassForName/index.html

(a paper by Ted Neward explaining the subtleties in the Java classloader
model: a worthwhile read for anyone doing web app development).

Thanks for contributing!

Cheers,

Nicholas Lesiecki
-----Original Message-----
From: Volkmann, Mark [mailto:Mark.Volkmann@AGEDWARDS.com]
Sent: Thursday, February 21, 2002 7:12 AM
To: 'Fred Loney'; 'cactus-user@jakarta.apache.org'
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:loney@spiritedsw.com]
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.
************************************************************************
***************


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: java.lang.NoClassDefFoundError: org/apache/cactus/ServletTestCase

Posted by Fred Loney <lo...@spiritedsw.com>.
RE: java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCaseNicholas and Mark,

Thanks to you both for your astute observations. Unfortunately,
recompiling with the patch and promoting the cactus dependent jars to
the system app classloader didn't resolve the problem for my particular
JBoss/Jetty configuration. JBoss, Jetty and junit each have their own
classloaders and I suspect that not all of them conform to the Java2
classloader javadoc recommended behavior.

I isolated the problem to a ServletTestCase subclass packaged at the ear
lib level rather than the war. The ear libs are referenced in the ejb
jar manifest classpath, and thus placed by the ejb container in a common
ear classloader that is the parent of the servlet container war
classloader. cactus.jar and junit.jar were not accessible when placed in
either the war lib or the system classpath.

When placed in the JBoss container classpath, cactus could not access
the javax.servlet class and raised yet another ClassDefNotFound. That is
because the JBoss classpath jars are apparently loaded by a parent of
the JBoss config jar classloader, where all significant J2EE jars
reside. Furthermore, log4j cannot be moved to the parent classloader
without causing a JBoss startup exception. I didn't try the extension
classloader, but I suspect that any work-around will merely push the
problem to another place.

The solution was to ensure that all ServletTestCase subclasses are in
the war classes or a war lib rather than a common ear lib.

Thanks again for the advice, which pointed me in the right direction. I
now know far more than I ever wanted to about classloaders.

Fred Loney
Spirited Software, Inc.
www.spiritedsw.com

----- Original Message -----
From: Nicholas Lesiecki
To: Cactus Users List ; 'Fred Loney'
Cc: Cactus Dev List
Sent: Thursday, February 21, 2002 11:17 AM
Subject: RE: java.lang.NoClassDefFoundError:
org/apache/cactus/ServletTestCase


Mark,

Thank you for this submission. Essentially, I'd like to integrate your
change and then re-run the unit tests against several containers
(Tomcat, Resin, Orion, etc.) to make sure that it has no unintended
consequences for the "standard" configuration.

Off hand, I think your patch will make cactus configuration
substantially more forgiving. I'm looking forward to using it myself :)

As background to this change, interested developers should check out:

http://www.javageeks.com/Papers/ClassForName/index.html

(a paper by Ted Neward explaining the subtleties in the Java classloader
model: a worthwhile read for anyone doing web app development).

Thanks for contributing!

Cheers,

Nicholas Lesiecki
-----Original Message-----
From: Volkmann, Mark [mailto:Mark.Volkmann@AGEDWARDS.com]
Sent: Thursday, February 21, 2002 7:12 AM
To: 'Fred Loney'; 'cactus-user@jakarta.apache.org'
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:loney@spiritedsw.com]
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.
************************************************************************
***************


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>