somewhat related issue I've found with T3.2.2.
After class reloading the old class isn't GC'ed, is a reference to previous
class that's kept around somewhere? Actually I noticed it because I had a
cleanup thread running infinitely, and after the class reload I ended up
having two threads running.

Could also be that runtime keeps a reference to a running Thread (which is
the inner class) preventing a class (outer class) from being GC'ed? Sounds
like a good explanation...

--V.



----- Original Message -----
From: "Craig R. McClanahan" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Sunday, August 19, 2001 8:25 PM
Subject: Re: ClassLoader & Reloading issues




On Mon, 20 Aug 2001, Andrés Aguiar wrote:

> I have a JAR file in my web-inf\lib directory that has an object pool. The
> pool is kept as a singleton, so, I have a static member with it.
>

And because the class itself is loaded by the webapp class loader, the
static is in fact global *only* within this particular web app.

> The problem is that when a class in web-inf\classes is reloaded, it seems
to
> use a new classloader,

That's correct -- there is no way to "unload" a class in Java except for
throwing away the class loader that loaded it (and therefore all of the
classes loaded by that old class loader).

> so the static member is gets not the same as it was,
> and I end having multiple object pool instances.
>
> If I put the .JAR in the Tomcat classpath, it obviously works ok.
>
> The problem is that I must keep running in the same servlet-engine
instance
> several applications each of which could a have a different version of my
> .JAR file, so I can't put it in the classpath.
>
> The same happens running the app in Resin.
>
> Now, in the servlet spec says:
>
> 'Although a Container Provider implementation of a class reloading scheme
> for ease of development is not required, any such implementation must
ensure
> that all servlets, and classes that they may use, are loaded in the scope
of
> a single class loader. This requirement is needed to guarantee that the
> application will behave as expected by the Developer.
>
> As a development aid, containers are encouraged to maintain the full
> semantics of notification to session binding listeners if they
> determine to terminate sessions in order to reload classes.
>
> Previous generations of containers created new class loaders to load a
> servlet, distinct from class loaders used to load other servlets or
classes
> used in the servlet context. This could cause object references within a
> servlet context to point at unexpected classes or objects, and cause
> unexpected behavior.'
>

Very early containers used a different class loader for every servlet, not
for every web app.  To ensure consistent behavior, this is no longer
allowed.

> I'm not sure if this paragraph is referring to the case I'm describing,
but
> if not, it seems pretty close...
>
> Any ideas? Is this the way it's supposed to work?
>

Yes, it is working the way it is supposed to work (given the limitations
on what Java allows for class "reloading").

What you need to do is make sure that your class is aware of when the
application is being shut down and started up again, so that you can save
away the contents of the object pool (at shutdown time) and restore them
(at startup time).  At shutdown time, you'll need to save the state of the
object pool in some fashion that can be used to reconstruct it upon the
subsequent startup.  A common technique is to serialize the pooled objects
to a sequential file (Tomcat 4 does this with all of the currently active
sessions when you shut it down or do an application reload).

To make sure your object pool class is notified, you've got a couple of
choices:

* [Servlet 2.3 only] You can use the new application event listener
  APIs and make sure your class is notified on the application startup
  and application shutdown events.  This will work in Tomcat 4 and other
  containers that implement the new servlet spec.

* You might have a servlet defined as <load-on-startup> that initializes
  the object pool in its init() method and saves it away in its destroy()
  method.  This depends on the servlet container *not* removing this
  servlet from service at any time *other* than application shutdown --
  while commonly implemented that way, this is not guaranteed by the
  servlet spec (it would work in all versions of Tomcat, though).

> Thanks.

Craig McClanahan



Reply via email to