You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by "Scott M. Stirling" <ss...@mediaone.net> on 2001/01/06 01:21:25 UTC

Re: cvs commit: jakarta-tomcat/src/share/org/apache/jasper/compiler Compiler.java

OK, I am thinking this is a pretty good idea now too, since seeing your and Marc's emails.  My last two thoughts on the matter (just playing Devil's advocate):

1. Doesn't it seem a bit sloppy to leave a bunch of classes loaded that
will never get dumped unless the server is shutdown?  Just a matter of
elegance, I suppose.

2. What unforseen problems might arise in a large application with
interdependencies, such as included files that are overlooked -- if an
included file is deleted but the includer is not, what happens?

-- 
Scott Stirling
West Newton, MA

On 05 Jan 2001 15:58:07 -0800, Hans Bergsten wrote:
> Scott Stirling wrote:
> > 
> > I agree with Craig.
> > 
> > The ability to run JSP apps without any source JSPs must be maintained
> > for app vendors who want to ship without source code.  Not sure if this
> > patch would interfere with that or not.
> 
> It shouldn't; if you want to distribute JSP pages without source,
> you compile them to servlet classes and add mappings for the
> paths to the servlets in web.xml. The spec may be vague on this,
> but that's still what I believe is the recommendation stated in
> the section about precompilation.
> 
> > A separate issue: if a user removes the source JSP, it may be OK to
> > remove the JSP class file, but what about the class loaded in memory
> > (assuming the server was running when the JSP was deleted)?  To be
> > consistent you would have to unload that JSP class, 
> 
> Not necessarily unload, but remove all internal (automatic) mappings
> so that a request for the JSP always results in a 404.
> 
> > and possibly any
> > associated objects (depending how JavaBeans and JSP are loaded in
> > classloaders in Tomcat).  For example, if an application scope bean were
> > loaded by that JSP, would that bean be dumped with the classloader for
> > that JSP or not?
> 
> Hmmm... I think that's overkill.
> 
> Hans



Re: cvs commit: jakarta-tomcat/src/share/org/apache/jasper/compiler Compiler.java

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
"Scott M. Stirling" wrote:

> On 05 Jan 2001 16:35:09 -0800, Hans Bergsten wrote:
> > "Scott M. Stirling" wrote:
> > > 1. Doesn't it seem a bit sloppy to leave a bunch of classes loaded that
> > > will never get dumped unless the server is shutdown?  Just a matter of
> > > elegance, I suppose.
>
> [Hans Bergsten]
>
> > Yes, it does. But AFAIK there's no way you can just unload a class
> > from the JVM; you would have to drop the class loader for the
> > context and reload all classes that are still valid. That doesn't
> > seem like the right thing to do in this situation IMHO.
>
> It depends how class loading in Tomcat works.  I'm familiar with JRun
> 3.0, which works like this (I'm not giving away any family secrets, this
> stuff is documented in various places in Allaire docs):
>

I'm not giving away family secrets either ... it's all out there in the source
code :-)

>
> - servlets & JavaBeans (even those called by JSPs) - loaded by a
> classloader with web-app scope.  If a single servlet changes, the whole
> web-app's classloader is dumped so the servlet can be dynamically
> reloaded.  No need to actively reload the other classes that got dumped
> with the classloader.  They'll be reloaded as needed when requests come
> in for them.
>

Tomcat does pretty much the same thing.  How reload checking is implemented
depends on which version you're talking about (assuming you've marked your app
for reload checking):

* Tomcat 3.2 - on each request, it checks the servlet you asked
  for, and reloads the entire webapp if it's been updated.  This is
  why it sometimes misses changes to bean classes.

* Tomcat 4.0 - a background thread checks for updated classes
  (default interval is 15 seconds), and reloads the wbapp if any have
  been changed.

In neither case are classes loaded from the shared library directory
($CATALINA_HOME/lib), or any higher-level classloader, checked for updates.  The
reason is that we cannot throw those classes away anyway, without throwing away
*all* of the current webapps.

When Tomcat reloads a webapp, it also attempts to save all the current sessions
(and their attributes, if they are Serializable) and reloads them again.  This
is necessary because the bean classes were loaded by the "old" webapp class
loader, so attempting to reference them from a bean class loaded by the "new"
webapp class loader (after the reload has been completed) would cause a
ClassCastException (even though the class names are the same).

>
> - JSPs are each loaded in their own classloader.  So if a JSP is changed
> and reloaded, the old classloader is dumped and a new one created.
> JavaBeans are delegated to the web-app classloader, for whatever reason.
>

Jasper does the same, and makes the webapp classloader the parent of the JSP
page classloader so that a page can reference beans and other classes known only
to the webapp.  For Tomcat 3.2, which has to run under JDK 1.1, the Java2
delegation model is essentially faked by custom ClassLoader implementations to
reproduce the "parent" relationship.

Jasper also plays some wierd games with the classnames of the generated pages --
this is an area I think needs to be cleaned up in the 4.1 time frame, as Jasper
is migrated to using Java2 facilities directly (because servlet 2.3 and JSP 1.2
require a Java2 platform).

>
> All this may change in future versions, when JRun reloads tag handlers
> dynamically.  I have no idea how Tomcat handles these classloader
> issues, but it would be interesting to hear about if anyone can distill
> it briefly.
>

Right now, Tomcat will treat changes to tag library classes just like it does to
bean or servlet classes, and chucks the whole webapp.  It might be worth looking
at whether you can get away with doing less than that for tags.

>
>
> --
> Scott Stirling
> West Newton, MA
>

Craig McClanahan



Re: cvs commit: jakarta-tomcat/src/share/org/apache/jasper/compiler Compiler.java

Posted by Glenn Nielsen <gl...@voyager.apg.more.net>.
"Scott M. Stirling" wrote:
> 
> On 05 Jan 2001 16:35:09 -0800, Hans Bergsten wrote:
> > "Scott M. Stirling" wrote:
> > > 1. Doesn't it seem a bit sloppy to leave a bunch of classes loaded that
> > > will never get dumped unless the server is shutdown?  Just a matter of
> > > elegance, I suppose.
> 
> [Hans Bergsten]
> 
> > Yes, it does. But AFAIK there's no way you can just unload a class
> > from the JVM; you would have to drop the class loader for the
> > context and reload all classes that are still valid. That doesn't
> > seem like the right thing to do in this situation IMHO.
> 
> It depends how class loading in Tomcat works.  I'm familiar with JRun
> 3.0, which works like this (I'm not giving away any family secrets, this
> stuff is documented in various places in Allaire docs):
> 
> - servlets & JavaBeans (even those called by JSPs) - loaded by a
> classloader with web-app scope.  If a single servlet changes, the whole
> web-app's classloader is dumped so the servlet can be dynamically
> reloaded.  No need to actively reload the other classes that got dumped
> with the classloader.  They'll be reloaded as needed when requests come
> in for them.
> 
> - JSPs are each loaded in their own classloader.  So if a JSP is changed
> and reloaded, the old classloader is dumped and a new one created.
> JavaBeans are delegated to the web-app classloader, for whatever reason.
> 
> All this may change in future versions, when JRun reloads tag handlers
> dynamically.  I have no idea how Tomcat handles these classloader
> issues, but it would be interesting to hear about if anyone can distill
> it briefly.
> 

Tomcat has a webapp classloader and Jasper has a class loader for JSP pages.
The webapp classloader is caching everything loaded from  the WEB-INF/classes 
or WEB-INF/lib directories.

Since Jasper is running within the web app, if the webapp context gets
reloaded, jasper gets reloaded.  Jasper IMHO is convoluted in the way
it loads JSP's. It munges the names when creating the java source and
class, and increments each of these files each time the JSP is compiled.
All those old versions of the classes stay resident in the Jasper
class loader and all the old java and class files clutter up the work dir.

While I am implementing the Java SecurityManager in Tomcat 4 I am also 
going to cleanup how Jasper loads classes so that there is one URLClassLoader 
per JSP page.  And that URLClassLoader gets reinstantiated when the JSP
page gets recompiled.

Regards,

Glenn

----------------------------------------------------------------------
Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
MOREnet System Programming               |  * if iz ina coment.      |
Missouri Research and Education Network  |  */                       |
----------------------------------------------------------------------

Re: cvs commit: jakarta-tomcat/src/share/org/apache/jasper/compiler Compiler.java

Posted by "Scott M. Stirling" <ss...@mediaone.net>.
On 05 Jan 2001 16:35:09 -0800, Hans Bergsten wrote:
> "Scott M. Stirling" wrote:
> > 1. Doesn't it seem a bit sloppy to leave a bunch of classes loaded that
> > will never get dumped unless the server is shutdown?  Just a matter of
> > elegance, I suppose.

[Hans Bergsten]

> Yes, it does. But AFAIK there's no way you can just unload a class
> from the JVM; you would have to drop the class loader for the
> context and reload all classes that are still valid. That doesn't
> seem like the right thing to do in this situation IMHO.


It depends how class loading in Tomcat works.  I'm familiar with JRun
3.0, which works like this (I'm not giving away any family secrets, this
stuff is documented in various places in Allaire docs):

- servlets & JavaBeans (even those called by JSPs) - loaded by a
classloader with web-app scope.  If a single servlet changes, the whole
web-app's classloader is dumped so the servlet can be dynamically
reloaded.  No need to actively reload the other classes that got dumped
with the classloader.  They'll be reloaded as needed when requests come
in for them.

- JSPs are each loaded in their own classloader.  So if a JSP is changed
and reloaded, the old classloader is dumped and a new one created.
JavaBeans are delegated to the web-app classloader, for whatever reason.

All this may change in future versions, when JRun reloads tag handlers
dynamically.  I have no idea how Tomcat handles these classloader
issues, but it would be interesting to hear about if anyone can distill
it briefly.
   

-- 
Scott Stirling
West Newton, MA


Re: cvs commit: jakarta-tomcat/src/share/org/apache/jasper/compiler Compiler.java

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
"Scott M. Stirling" wrote:
> 
> OK, I am thinking this is a pretty good idea now too, since seeing your 
> and Marc's emails.  My last two thoughts on the matter (just playing Devil's 
> advocate):

That's good. It's easy to overlook some problems.

> 1. Doesn't it seem a bit sloppy to leave a bunch of classes loaded that
> will never get dumped unless the server is shutdown?  Just a matter of
> elegance, I suppose.

Yes, it does. But AFAIK there's no way you can just unload a class
from the JVM; you would have to drop the class loader for the
context and reload all classes that are still valid. That doesn't
seem like the right thing to do in this situation IMHO.

> 2. What unforseen problems might arise in a large application with
> interdependencies, such as included files that are overlooked -- if an
> included file is deleted but the includer is not, what happens?

If it's included with the JSP directive, the includer will still
exist and be served, since the directive include works at translation
time. Tomcat (Jasper) doesn't keep track of the relationship to
included files, so it's similar to what happens if you change the
included file; nothing ;-)

If it's included using the JSP include action, a request for the
includer will fail, hopefully with a 404-like message. It's the
same as if you use an include action to include a JSP page or
servlet that has never existed.

Hans
-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com
Author of JavaServer Pages (O'Reilly), http://TheJSPBook.com