2009/10/11 Adam Monsen <hair...@gmail.com>: > I have a Web application which includes an abstract class: > "TransactionImport". > > I compiled a subclass of TransactionImport (AudiBankImporter), placed > the class in a jar, then placed the jar in $CATALINA_HOME/lib. > > What I'd like to do is load the compiled AudiBankImporter class from > the Web application at runtime. When I do this using Class.forName() > or ClassLoader.loadClass(), I get "java.lang.NoClassDefFoundError: > TransactionImport". > > If I change AudiBankImporter so that it no longer subclasses > TransactionImport, I am able to load the class. > > I feel like I'm missing something fundamental about class loading in > general or Tomcat classloaders, but I don't know what.
You don't say which version of Tomcat you're using, but I guess 6.0 from your paths. You should take a close look at http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html . You're being bitten by the problem that the classloader that loads AudiBankImporter cannot find TransactionImport. Two classloaders are involved in your example: 1) The common classloader, which loads from CATALINA_HOME/lib - and only there. This has no knowledge of classes inside individual webapps, and no way of loading them. 2) The webapp classloader responsible for loading your webapp's classes. This has no knowledge of CATALINA_HOME/lib. If it can't load a class, it delegates up the chain. So you ask for Class.forName("AudiBankImporter"). The webapp classloader can't load this, so delegates to the common classloader. The common classloader loads the class and tries to resolve the class' references to other classes. It tries to resolve the reference to TransactionImport; can't find it; delegates up the chain; still can't find it; and fails with the error you see. If you really, really have to do it this way (and it seems like a rather odd thing to do), you'll need to ensure that the common classloader can resolve TransactionImport. This means that you then should ensure TransactionImport is *not* loaded by your webapp classloader - you need to move it out of your webapp to CATALINA_HOME/lib. Equally, you could put the jar containing AudiBankImporter into your webapp, which seems like a simpler and more isolated approach unless you're trying to solve a larger problem than you've described! Hope this helps to identify the problem, if not to resolve it. - Peter --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org