Singletons in webapps

Has anyone hit any problems relating to singletons and running web apps inside of IDEA?

After loading 2 webapps and reloading one of them, I now have distinct 2 instances of a singleton.

The singleton skeleton is:
public class SessionMgr
{
private SessionMgr instance = new SessionMgr();

public SessionMgr getInstance()
{
return instance;
}

private SessionMgr() {}
}

yet I have two object references now to the singleton.

Am I missing something here, or is this just wrong?
Is this something to do with the ClassLoader inside of my servlet container (in this case, Tomcat 5.0.26) someone loading two copies of the same class? (I thought this was not supposed to happen? )

Or am I getting two separate and independant instances of the "singleton" in the same VM because I have a class loader per web application context?

Nick

4 comments

To reproduce (in case this is a bug and not me being dumb) :
Create singleton class, put it in a.jar

Create 2 web apps, b.war, c.war which both use a.jar via the getInstance() method of the singleton. Stick a simple hello world servlet in each WAR.

Print out the address of the singleton in the constructor of the singleton class.

Make a change to c.war.
Redeploy.
The singleton constructor gets called again.

Nick

0

Nick Pratt wrote:

To reproduce (in case this is a bug and not me being dumb) :
Create singleton class, put it in a.jar

Create 2 web apps, b.war, c.war which both use a.jar via the getInstance() method of the singleton. Stick a simple hello world servlet in each WAR.

Print out the address of the singleton in the constructor of the singleton class.

Make a change to c.war.
Redeploy.
The singleton constructor gets called again.


A singleton in Java is only a singleton within the ClassLoader which
loaded its class. If another ClassLoader is created which doesn't have
the first ClassLoader as an ancestor, then it will load and initialize
its own version of the singleton class. Tomcat is probably using a
separate ClassLoader for each WAR.

You may wish to re-examine why you are using a singleton and use a
different design that will accomplish the same thing.

Ciao,
Gordon

--
Gordon Tyler (Software Developer)
Quest Software <http://java.quest.com/>
260 King Street East, Toronto, Ontario M5A 4L5, Canada
Voice: (416) 933-5046 | Fax: (416) 933-5001

0

As I suspected.
The reloading triggers a new singleton.

I am trying to pass authentication info between a central web app and various others that hang off it.
Due to the existing, and "wont-be-changed" design of the authentication, I was trying to pass a "Session" type object between different WARs. I planned on doing this using a Singleton, and have the calling app push the Session into the singleton, and the receiving app, pop it.

Im in the middle of changing to just pass everything as a series of request parameters.

Im also aware of the shared context stuff in Tomcat, but that involves playing with existing settings on the deployed apps, and that isnt an option.

Thanks

Nick

0

WebApps have been around for how many years with the Never-Do-Static-Singletons rule? Don't do it because this happens! Use the ServletContext.

0

Please sign in to leave a comment.