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

Reply via email to