You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Gary Hirschhorn <gh...@fetch.com> on 2008/10/17 02:54:30 UTC

Classes in tomcat\server\lib folder sometimes are visible to web application

We are using Tomcat 5.5.17 and are using a custom ClassLoader, which we
specify using the Loader element per the documentation at
http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html.

 

We place the jar containing our custom ClassLoader in the
tomcat\server\lib folder, per the documentation at
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html.  (I
forget why we did this originally, but I think we had problems if we put
it elsewhere.)  According to this documentation, classes in this jar
should be TOTALLY invisible to web applications.  And indeed, for the
most part, if we try to reference some class  in this jar, we get a
java.lang.NoClassDefFoundError.  What is strange, however, is that
sometimes the web-app does seem to find classes in this jar.   Even more
strange, it does not seem to be deterministic.  The app will work for a
few days, and then it won't.  So I understand why it does not work
(class should not be visible), but why does it ever work?

 

Does anyone have any thoughts on what might be going on?

 


RE: Classes in tomcat\server\lib folder sometimes are visible to web application

Posted by Gary Hirschhorn <gh...@fetch.com>.
Hi Chuck,

Thank you very much for your feedback. Your comments about reflection
were right on the money and have helped me resolve the underlying issue.
It turns out that my initial assertion about our server/lib classes
being visible to our web app was incorrect -- it was just that our
custom classloader was SOMETIMES loading these classes from a different
location, and therefore no error was reported.  This situation was the
result of other problems we had, but your comments have helped me
develop a much cleaner solution.  

In order to help others, here is our resolution:

Background: We have a simple custom ClassLoader that uses a number of
helper classes to determine which jars on our system should be loaded
from some well-known location (instead of just using jars in the
WEB-INF/lib folder). We bundle the custom ClassLoader and the helper
classes in a jar together. The custom ClassLoader obviously needs to be
loaded by Tomcat, and the helper classes are used not only by our custom
ClassLoader, but by our web app as well. 

First attempt: Since the helper classes are also used by the web-app
itself, our initial plan was to place this jar in common/lib.  However,
this results in Tomcat errors because the custom class loader can't
exist in common/lib because it extends WebappClassLoader, which exists
in server/lib and is not visible to common/lib. 

Second attempt: So we moved the combined jar to server/lib. Tomcat now
uses the custom ClassLoader fine, but our web app can't see the helper
classes, because they are in the Tomcat-private shared/lib folder.

Third attempt: We place a duplicate of the combined jar in the
well-known location for our custom ClassLoader to find. For the most
part, this works okay, but it is very klugey, sometimes leads to errors,
and is hard to debug. This is because we now have the same helper
classes being loaded twice by different ClassLoaders. 

Final solution:  Break the custom ClassLoader and helper classes into
two jars.  The custom ClassLoader goes in server/lib, and the helper
classes go in common/lib.  We now no longer need to duplicate the jars
-- all classes are loaded by only one ClassLoader.  And the one part of
our system where the wep-abb needs to call a custom ClassLoader-specific
method is handled by reflection rather than by casting the ClassLoader
and making a direct call.

Once again, thanks for spending the time to respond so thoroughly and
accurately.

Regards,
Gary



-----Original Message-----
From: Caldarale, Charles R [mailto:Chuck.Caldarale@unisys.com] 
Sent: Friday, October 17, 2008 11:27 AM
To: Tomcat Users List
Subject: RE: Classes in tomcat\server\lib folder sometimes are visible
to web application

> From: Gary Hirschhorn [mailto:ghirschhorn@fetch.com]
> Subject: RE: Classes in tomcat\server\lib folder sometimes
> are visible to web application
>
> The Catalina ClassLoader in server/lib creates Webapp1 ClassLoader
> specifically for webapp1.

It's actually org.apache.catalina.loader.WebappLoader that creates each
webapp's classloader, but the result is the same as you surmised.

> the only way for this to work in practice is that these specific
> implementations are referenced in Webapp1 as Interfaces which are
> defined NOT in server/lib, but rather by jars higher up in hierarchy,
> such as common/lib.

Essentially correct; in addition to Interface classes, there are also
abstract classes in the top-level jars.

> a) if my webapp code has any specific reference (e.g. the
> Class name is in my code as a variable or parameter type)
> to a class in server/lib, I should get a ClassDefNotFoundError.

Correct.

> b) however, if my webapp has a reference to an Interface defined
> in common/lib and at runtime is handed a Class that implements
> this class, I may not get a ClassDefNotFoundError.

Not just may not, but should not.

Be aware that Tomcat uses a fair amount of reflection to avoid having
direct references at compile and load time; depending on what your code
needs, you may have to do something similar.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Classes in tomcat\server\lib folder sometimes are visible to web application

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Gary Hirschhorn [mailto:ghirschhorn@fetch.com]
> Subject: RE: Classes in tomcat\server\lib folder sometimes
> are visible to web application
>
> The Catalina ClassLoader in server/lib creates Webapp1 ClassLoader
> specifically for webapp1.

It's actually org.apache.catalina.loader.WebappLoader that creates each webapp's classloader, but the result is the same as you surmised.

> the only way for this to work in practice is that these specific
> implementations are referenced in Webapp1 as Interfaces which are
> defined NOT in server/lib, but rather by jars higher up in hierarchy,
> such as common/lib.

Essentially correct; in addition to Interface classes, there are also abstract classes in the top-level jars.

> a) if my webapp code has any specific reference (e.g. the
> Class name is in my code as a variable or parameter type)
> to a class in server/lib, I should get a ClassDefNotFoundError.

Correct.

> b) however, if my webapp has a reference to an Interface defined
> in common/lib and at runtime is handed a Class that implements
> this class, I may not get a ClassDefNotFoundError.

Not just may not, but should not.

Be aware that Tomcat uses a fair amount of reflection to avoid having direct references at compile and load time; depending on what your code needs, you may have to do something similar.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Classes in tomcat\server\lib folder sometimes are visible to web application

Posted by Gary Hirschhorn <gh...@fetch.com>.
Thank you for your quick reply. I think I understand the distinction you
make between a class being available and a class being loaded, although
it is a bit confusing.  I suspect that if I understand this clearly, it
will help me track down the cause of my problem.

Given the Tomcat ClassLoader hierarchy diagram in the documentation and
your clarification below, is the following correct?

The Catalina ClassLoader in server/lib creates Webapp1 ClassLoader
specifically for webapp1.  The parent classloader of Webapp1 ClassLoader
is NOT set to Catalina ClassLoader but rather to Shared ClassLoader, so
requests from webapp1 to load classes are never delegated to Catalina
ClassLoader.  Thus a reference to a Class in server/lib in Webapp1 will
result in a ClassDefNotFound error.  However, the classes in sever/lib
ARE aware of WebApp1, and may call methods in Webapp1 and pass in
references to themselves.  When this happens, Webapp1 is now working
with an implementation of a class in server/lib.  I assume, however,
that the only way for this to work in practice is that these specific
implementations are referenced in Webapp1 as Interfaces which are
defined NOT in server/lib, but rather by jars higher up in hierarchy,
such as common/lib.

If this understanding is true, then
a) if my webapp code has any specific reference (e.g. the Class name is
in my code as a variable or parameter type) to a class in server/lib, I
should get a ClassDefNotFoundError.
b) however, if my webapp has a reference to an Interface defined in
common/lib and at runtime is handed a Class that implements this class,
I may not get a ClassDefNotFoundError.

Regards,
Gary

-----Original Message-----
From: Caldarale, Charles R [mailto:Chuck.Caldarale@unisys.com] 
Sent: Thursday, October 16, 2008 6:55 PM
To: Tomcat Users List
Subject: RE: Classes in tomcat\server\lib folder sometimes are visible
to web application

> From: Gary Hirschhorn [mailto:ghirschhorn@fetch.com]
> Subject: Classes in tomcat\server\lib folder sometimes are
> visible to web application
>
> According to this documentation, classes in this jar
> should be TOTALLY invisible to web applications.

That's not quite the case.  Classes outside of a given classloader's
branch can not be *loaded* by that classloader.  However, if references
to instances of such "outside" classes are made available to code from
the classloader branch of interest, that code can use those objects.

Nearly all of Tomcat's code, including the classloaders,
request/response wrappers, servlet API handlers, etc., are in
server/lib, yet are obviously used by application servlet code.

> So I understand why it does not work (class should not
> be visible), but why does it ever work?

Without seeing the code, it's difficult to even speculate.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Classes in tomcat\server\lib folder sometimes are visible to web application

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Gary Hirschhorn [mailto:ghirschhorn@fetch.com]
> Subject: Classes in tomcat\server\lib folder sometimes are
> visible to web application
>
> According to this documentation, classes in this jar
> should be TOTALLY invisible to web applications.

That's not quite the case.  Classes outside of a given classloader's branch can not be *loaded* by that classloader.  However, if references to instances of such "outside" classes are made available to code from the classloader branch of interest, that code can use those objects.

Nearly all of Tomcat's code, including the classloaders, request/response wrappers, servlet API handlers, etc., are in server/lib, yet are obviously used by application servlet code.

> So I understand why it does not work (class should not
> be visible), but why does it ever work?

Without seeing the code, it's difficult to even speculate.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org