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:[EMAIL PROTECTED]] Sent: Thursday, February 21, 2002 7:12 AM 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. ************************************************************************ *************** -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
