25

If I deploy and run 2 instances of same application on a single instance of Tomcat(Or any other server). Then a single object(of a Singleton class) would be created:

  1. Across single instance of Tomcat (but common for 2 instances of same application) OR
  2. Across application instance (different for 2 instances of application)

So essentially I want to understand that is it always a case that a single object of Singleton class gets created per JVM? How does this works in case of application hosted on a Web server(or container).

Learner
  • 1,503
  • 6
  • 23
  • 44

5 Answers5

35

If you have a singleton class and you run two webapps that use this class in Tomcat both webapps will get 2 different instances of this singleton in JVM running the Tomcat.

But if your webapp will use a singleton from JRE or Tomcat shared libs, eg Runtime.getRuntime webapps will get the same instance of Runtime.

This is because Tomcat uses individual class loaders for webapps. When a webapp class loader loads a class it first tries to find it on webapp class path, if the class is not found it asks parent class loader to load the class.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • 2
    @Evgenniy, Does this mean that in my single application I can create 2 singleton objects using different class loaders(Just a thought).?? – Learner Jul 30 '13 at 08:15
  • 1
    Yes, create 2 classloaders (you can use URLClassLoader), load the same class with ClassLoader.loadClass(className) - you will get 2 different Class instances – Evgeniy Dorofeev Jul 30 '13 at 08:22
  • Does that mean Singleton is broken? – Learner Jul 31 '13 at 06:47
  • 2
    No, thanks to that different server apps running in different classloaders behave as if they are running in two independent JVMs – Evgeniy Dorofeev Jul 31 '13 at 07:01
  • flawless answer! – Gaurav Jun 06 '20 at 13:51
  • @EvgeniyDorofeev What about resources mentioned in JNDI of tomcat ? Will same object be shared ? Please answer for following cases - Case 1) Same tomcat instance running multiple WARS deployed. Case 2) 1 Tomcat cluster with multiple tomcat nodes (same or different physical machine). On each of these nodes, one or more WebApp deployed – Number945 Jan 02 '21 at 19:02
24

A singleton is normally tied to a ClassLoader only.

So if you have a singleton based on a .class file in your .war file, and you deploy this web application multiple times, each application gets its own singleton.

On the other hand, if the .class file of your singleton is in the classpath of tomcat, then you only have one instance. This .class does not belong to a specific web application (it belongs to the tomcat instance).

If you have the singleton in both locations, it depends on the class loader hierarchy, and you can possibly select between "parent first" or "web application first".

Beryllium
  • 12,808
  • 10
  • 56
  • 86
  • @Beryllium what do you mean by "classpath of tomcat" ? I mean where shall i pur my class/jar so that i get singleton across applications. – Vipin Feb 25 '14 at 04:53
  • @vipin I can't tell for sure, because I haven't done it lately, but try to put a .jar file into tomcat's lib/ directory. As for JBoss 7 they effectively do the same, they just organize it as "modules". – Beryllium Feb 25 '14 at 07:43
  • @Beryllium long back I read an article which says we should not put any of our jar in tomcat/lib. Recently i did some reserch and found we can use shared.loader attribute of catalina.properties. But not sure it will work or not. – Vipin Feb 25 '14 at 08:34
  • @Beryllium I was refering this article http://www.mulesoft.com/tcat/tomcat-classpath. Please Read "Problem: I want multiple applications to share a single JAR file, and I want this JAR files to reside within Tomcat." Does it answer same problem of one instance for all webapp ? – Vipin Feb 25 '14 at 08:41
  • @vipin I was not aware of that shared library path in addition to tomcat's lib/ directory, but according to that document you get a singleton, if a class is loaded from there. Anyway they recommend it, so give it a try. – Beryllium Feb 25 '14 at 23:05
5

It is possible to create such a singleton by assuring that you always query the same ClassLoader for the singleton. I wrote an extensive explanation in this other answer.

Community
  • 1
  • 1
Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
5
  • The Tomcat creates new class loader for each web application.
  • So if your Singleton class is stored in war file, the same war file will have two instances in Tomcat container i.e. it creates two separate Singleton class for each war file.
  • If the Singleton class is in Tomcat's share library path, Tomcat creates only one Singleton instance for the both application.

JVM analogy:

JVM is like big mansion. It contains combined family with serveral applicance and libraries.

ClassLoaders are family members, each family member represents one ClassLoader (works as delegate hierarchy not inheritance hierarchy). Note: ClassLoader is class, it can create multiple instances.

Applications are like appliance. for example: Washing Machine, Fridge, Air Cooler, Television, Dining table, Sofa and so on...

Libraries are each one having his own individual library. Every one search in parent's library if not found then search in his own library.

limitations: If father buy an appliance their children can use it, but it can not used by his parent and siblings. Each application might use different versions of the same libraries. i.e. If library contain two or more versions of same books, it picks whichever the book is available first.

Each family number can use only one unique appliance.

In home, we can use multiple appliance of same version. So, JVM allows us to run multiple applications of same versions.

Garbage Collector is a servant in Mansion, who roams as a daemon, who can clear any kind of Objects.

The scope of a static variable is limited to one per ClassLoader.

Premraj
  • 72,055
  • 26
  • 237
  • 180
1

<shakey-ground>As far as I know, a singleton is unique per classloader. So I think the answer to your question depends on the way the container loads the web application.

If it allocates one classloader per web app, then it seems like you would get two, completely independent, singleton objects. If it allocates one classloader and all web apps use it, then they share the same singlet one instance.</shakey-ground>

DaveH
  • 7,187
  • 5
  • 32
  • 53