This is an interesting one.
I had assumed that statics were a nono in webapps
because they broke Context encapsulation.
It appears, however, that you can have your cake
and eat it. At least in TC 3.2.1.
I declared a public static String in a Base servlet
and built the host webapp twice, with two different
values in this String into 2 war files with different
names. After starting TC I could see that the same
static String had different values in the 2 Contexts.
I have just reread the 2.2 spec and do not recall seeing
anything that suggested that compliant containers must
behave like this. Did I miss something?
Given that it seems one can safely use statics in webapps,
is there anything now to be said against this?
Miles Daffin
> -----Original Message-----
> From: craigmcc@localhost [mailto:craigmcc@localhost]On Behalf Of Craig
> R. McClanahan
> Sent: Monday, August 20, 2001 4:26 AM
> To: '[EMAIL PROTECTED]'
> 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
>
>
>