tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject RE: Problem with loading classes dynamically, new objects can't " see" things in webapp.
Date Tue, 11 Sep 2001 15:54:35 GMT


On Tue, 11 Sep 2001, Guy Verbist wrote:

> Date: Tue, 11 Sep 2001 16:49:14 +0100
> From: Guy Verbist <guy.verbist@prosumersolutions.com>
> Reply-To: tomcat-user@jakarta.apache.org
> To: "'tomcat-user@jakarta.apache.org'" <tomcat-user@jakarta.apache.org>
> Subject: RE: Problem with loading classes dynamically,
>      new objects can't " see"  things in webapp.
>
> Hi Craig, and thanks for your reply.
>
> > Because you got NoClassDefFoundError instead of
> > ClassNotFoundException, it is *not* ProsumerTestTag that is the
> > missing one.  Instead, check the
> > sources of ProsumerTag for references to *other* classes, and
> > make sure all of *those* classes are also available in your web app.
>
> Yes, I'm aware of this.
>
> ProsumerTestTag isn't in the webapp, but I've put it in the classpath, and
> that's fine.
>

Not necessarily.  See below.

> It can't find com.psl.customtags.CustomTag which is an interface that that
> the ProsumerTestTag class implements.  This class (CustomTag) really is in
> the web app, honest.
>

If ProsumerTestTag is being loaded from the class path, it's being loaded
by the system class loader.

If CustomTag is being loaded from the web app, it is being loaded from the
webapp class loader.

Classes loaded from the system class loader CANNOT see classes loaded from
the webapp class loader -- therefore, Tomcat is telling you the truth.
These restrictions are based on the way class loaders work in Java, so
there's nothing Tomcat can do about it.

Note that any of the following should work:
* Put CustomTag and ProsumerTestTag both on the classpath
* Put CustomTag and ProsumerTestTag both in the webapp
* Put CustomTag on the classpath and ProsumerTestTag in the webapp
  (webapp class loaders can look "up" the class loader hierarchy)

Craig

> If I pull just com.psl.customtags.CustomTag into the classpath, then as soon
> as I actually try to *do* something with the ProsumerTestTag class (as
> opposed to just loading it), then the jvm can't find other things in the
> webapp that CustomTag references (not just the interface it implements, but
> types that are parameters to it's methods).
>
> Many thanks,
>
> Guy
>
> > > Hi all.
> > >
> > > I hope I'm not being too dumb here.
> > >
> > > My servlet code wants to load classes dynamically at
> > runtime.  Instances of
> > > these classes will call back into the servlet code.
> > >
> > > So, my server.xml looks like this:
> > >
> > >     <Context path="/prosumer"
> > >          docBase="c:\Products\suite\current\peng\webapp"
> > >
> > > with all the class files under ...\webapp\WEB-INF\classes
> > >
> > > Mostly it works fine.
> > > However when I try to execute this line:
> > >
> > >     Class c =
> > Class.forName("com.psl.test.customtags.ProsumerTestTag");
> > >
> > > where ProsumerTestTag is defined thusly:
> > >
> > >     public class ProsumerTestTag implements CustomTag {
> > >
> > > tomcat keels over with:
> > >
> > > java.lang.NoClassDefFoundError: com/psl/customtags/CustomTag
> > > 	at java.lang.ClassLoader.defineClass0(Native Method)
> > > 	at java.lang.ClassLoader.defineClass(ClassLoader.java:486)
> > > 	at
> > >
> > java.security.SecureClassLoader.defineClass(SecureClassLoader.
> > java:111)
> > > 	at java.net.URLClassLoader.defineClass(URLClassLoader.java:248)
> > > 	at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
> > > 	at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
> > > 	at java.security.AccessController.doPrivileged(Native Method)
> > > 	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
> > > 	at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
> > > 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
> > > 	at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
> > > 	at
> > >
> > org.apache.tomcat.loader.AdaptiveClassLoader.loadClass(Adaptiv
> eClassLoader.j
> > > ava:446)
> > > 	at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
> > > 	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
> > > 	at java.lang.Class.forName0(Native Method)
> > > 	at java.lang.Class.forName(Class.java:120)
> > >
> > > left in the jvm.stderr
> > >
> > > I guess it can't find the "CustomTag" that ProsumerTestTag
> > implements.
> > > However com/psl/customtags/CustomTag *realy is* in the webapp.
> > >
> > > I'm running tomcat 3.2.2 as a service on a Win2k server
> > box, and if I add
> > > the whole of the webapp code to the classpath for the jvm
> > for tomcat by
> > > editing the ...wrapper.properties for jk_nt_service.exe,
> > then the whole
> > > thing works.  However this workaround seems to be suboptimal.
> > >
> > > My question is why can't a class loaded by Class.forName()
> > see things in
> > > webapp/WEB-INF/classes, only things in the regular JVM
> > classpath, when the
> > > rest of the webapp can see things in the webapp/WEB-INF/classes?
> > >
> > > I guess my call to Class.forName() is creating a different
> > context for the
> > > new class to what is created for the rest of the servlet,
> > but is there some
> > > way I can resolve the differences?
> > >
> > > Thanks very much.
> > >
> > > Guy
> > >
> >
>


Mime
View raw message