You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by John Tangney <jt...@knowledgeplanet.com> on 2000/08/15 23:39:38 UTC

Singleton Revisited

I know this topic has been discussed at length, and yes, I have scoured the
archives. But I still have questions.

Exactly *how* dangerous is it to use a static (to implement the singleton
pattern) in a JSP/Servlet environment? In the thread on this subject from
last April 
(http://archives.java.sun.com/cgi-bin/wa?A2=ind0004&L=jsp-interest&P=R16455&
D=0&m=12686ITEM+ITEM+) various learned folks, including Craig, Kevin and Wes
et al. seem to be in agreement that if you don't "own" the VM, are likely to
get into trouble.

Trouble, it seems, comes in several flavors: 1) Your "singleton" gets GC'd;
2) multiple instances of the "singleton" can get made as more than one class
loader and/or VM are involved; or 3) an instance shared across more than one
application opens potential security holes.

My question is just how bad is this? I have a single application (using
Craig's struts f/w) comprised of 2 or 3 servlets, we run under tomcat
(eventually under apache) and no one else runs any servlets on that host. We
run under JDK1.3.

How vulnerable am I? It seems to me that I can probably forge ahead and use
the singleton pattern with impunity. Has anyone had any *first hand*
problems with singletons?

Thanks!
--johnt


Re: Singleton Revisited

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Jim Rudnicki wrote:

> > For sharing information *within* a web app, the singleton pattern
> implemented
> > as a static variable is feasible and portable (although I dislike it for
> > "personal bias" reasons -- I've seen too many apps get messed up because
> any
> > code in the entire application can mess with those global variables,
> making
> > bugs hard to track down).
>
> Good, I thought that there would be only one classloader per webapp.  So all
> is well unless some decides to load balance for you and install the webapp
> on multiple machines.  Then the singleton would break again.
> What globals?  My singletons don't have any globals.
>

"Globals" in the sense I am talking about include singletons implemented as
public statics.  They are "global" in the sense that any Java code anywhere in
your app can access them, without requiring a reference to an object being
passed.

There is a class loader per web application.  In Java, "static" means "global
within a class loader".

Statics will "break" in a load balanced environment, but so would context
attributes.  You really end up having a copy of the singleton in each JVM.  Of
course, for something like a connection pool, this is exactly what you want to
have happen.

>
> Does a delegation model classloader break this?  Or, as long as the
> singleton is only one place (web-ing/classes) then the same loader will be
> used for the same webapp every time?
>

That's where life gets really interesting, because it depends on how the
application class loader is implemented.  In 2.2 there is considerable freedom
for container implementers (because the behavior is not specified).  This is
getting tightened quite a bit in 2.3 so there will be more predictability.

For Tomcat, as long as your classes are in either WEB-INF/classes or
WEB-INF/lib/*.jar, **and** there are no such classes on your system class path
(or placed in $TOMCAT_HOME/lib), then your "statics" will be global only within
the web app that loaded them.

>
> > For sharing information *across* web apps, the
> > servlet spec advises using external mechanisms (files, databases,
> directory
> > servers, etc.) to maintain portability.
>
> Okay, right, each webapp has a separate classloader.  But, this is good.
> You should not be able to share anything between webapps for security.
>

That's the basic reasoning in the servlet spec - another way to say it is that
web apps should be self contained (to the maximum degree possible) so that they
can be deployed on any container.

The ability to express a dependency on a particular external library, in a
portable way, is one of the other things being clarified in the 2.3 servlet
spec.

>
> Jim

Craig



Re: Singleton Revisited

Posted by Jim Rudnicki <jd...@pacbell.net>.
> For sharing information *within* a web app, the singleton pattern
implemented
> as a static variable is feasible and portable (although I dislike it for
> "personal bias" reasons -- I've seen too many apps get messed up because
any
> code in the entire application can mess with those global variables,
making
> bugs hard to track down).

Good, I thought that there would be only one classloader per webapp.  So all
is well unless some decides to load balance for you and install the webapp
on multiple machines.  Then the singleton would break again.
What globals?  My singletons don't have any globals.

Does a delegation model classloader break this?  Or, as long as the
singleton is only one place (web-ing/classes) then the same loader will be
used for the same webapp every time?

> For sharing information *across* web apps, the
> servlet spec advises using external mechanisms (files, databases,
directory
> servers, etc.) to maintain portability.

Okay, right, each webapp has a separate classloader.  But, this is good.
You should not be able to share anything between webapps for security.

Jim


Re: Singleton Revisited

Posted by Craig McClanahan <Cr...@eng.sun.com>.
Jim Rudnicki wrote:

>
> > 2) multiple instances of the "singleton" can get made as more than one
> class
> > loader and/or VM are involved;
>
> Not an easy way around this.  If you have one server, one jvm, one
> classloader. then I would hope that the singleton holds up.  Now you have me
> all worried.

Even in a single-JVM environment, a typical servlet container implementing the
2.2 spec will have more than one class loader defined.  For example, Tomcat
defines a class loader per web application -- that is how it implements making
classes under WEB-INF/classes and WEB-INF/lib available to each particular app.

The behavior of statics (in particular, whether they are global across web apps
or not) depends on which class loader loaded that class, and therefore depend
on how your particular servlet container does this.  You cannot count on
consistency across platforms.

For sharing information *within* a web app, the singleton pattern implemented
as a static variable is feasible and portable (although I dislike it for
"personal bias" reasons -- I've seen too many apps get messed up because any
code in the entire application can mess with those global variables, making
bugs hard to track down).  For sharing information *across* web apps, the
servlet spec advises using external mechanisms (files, databases, directory
servers, etc.) to maintain portability.

Craig



Re: Singleton Revisited

Posted by Jim Rudnicki <jd...@pacbell.net>.
Message
> > in init() you call getInstance() and store the reference in a member of
the
> > servlet class.  As long as the servlet exists, the singleton will exist.
Do
> > not use getInstance() in the service() method.  What is noted in that
thread
> > is how it should be I believe.

> I have used DBConnectionPool manager which is implemented by Singleton
Pattern in
> multi-threaded servlet environment. Because I have not done heavy load
performance test,
> I'm not sure the danger about the potential Singleton Pattern.

> Following above your notice, Should I never call getInstance method in
doPost or doGet?
> I have been calling getInstance in doPost and doGet method in serveral
servlets.
> Is it a dangerous thing? Why? In my environment, It seems to work fine.

Okay, it depends on your goals.  Some of my uses for a Singleton are the
goal of efficiency in reusing one object and for the goal of avoiding
construction and destruction hits.  Your db pool probably needs both of
these.  You do not want the entire pool to be gc'd and rebuilt between every
service().  To ensure that, something must retain a copy of the reference
you get from getInstance().  If you just store it in a local variable, it
goes away on return;

Now if you let go of your references, your servlets still will work--just
maybe not well.  You could be invoking the DBConnectionPool constructor on
_every_ doGet().  This would not show as a failure, just real slow
performance.

Jim





tomcat + apache SunOS 5.8 problems

Posted by "Abhilash V. Sonwane" <ab...@elitecore.com>.
Hi all,
i m having a peculiar problem. I have configured tomcat with apache on SunOS
5.8. All is working fine but tomcat shuts down/crashes after sometime and
this happens quite frequently. It doesn't give any message or doesn't
coredump
Do i need to do any xtra configurations or include any libraries ??
Need help urgently.

abhilash


Re: Singleton Revisited

Posted by Jim Rudnicki <jd...@pacbell.net>.
> Exactly *how* dangerous is it to use a static (to implement the singleton
> pattern) in a JSP/Servlet environment? In the thread on this subject from
...
> Trouble, it seems, comes in several flavors: 1) Your "singleton" gets
GC'd;

in init() you call getInstance() and store the reference in a member of the
servlet class.  As long as the servlet exists, the singleton will exist.  Do
not use getInstance() in the service() method.  What is noted in that thread
is how it should be I believe.

> 2) multiple instances of the "singleton" can get made as more than one
class
> loader and/or VM are involved;

Not an easy way around this.  If you have one server, one jvm, one
classloader. then I would hope that the singleton holds up.  Now you have me
all worried.