How does class loading work when the same class exists in different applications on the same server?

CodeClimber :

I have multiple web-apps running on an app server and each web-app WAR file contains a copy of the same jar file.

Does this mean that a class in that jar file will be loaded multiple times in the JVM, once for each WAR file it exists in? Following on from that, if I have a static synchronized method in such a class, is it only synchronized among threads within the web-app it exists in but not synchronized against the same method in the same class in a different jar file in a different WAR file? (Hope the question makes sense, will clarify if necessary).

If this is the case I presume the best solution is to remove the jar file from each WAR file and deploy it to a shared classpath folder on the server?

Stephen C :

A Java classloader typically works by looking for classes in one or more places in a fixed sequence. For instance, the classloader that loads your application when you run it from the command line looks first in the rt.jar file (and others on the bootclasspath), and then in the directories and JAR files specified by your classpath.

A webapp classloading is similar in principle, but a bit more complicated in practice. For a particular webapp, a webapp's classloader looks for classes in the following order. For example Tomcat 6 looks for classes in this order:

  1. Bootstrap classes of your JVM
  2. System class loader classes (described here)
  3. /WEB-INF/classes of the webapp
  4. /WEB-INF/lib/*.jar of the webapp
  5. $CATALINA_HOME/lib
  6. $CATALINA_HOME/lib/*.jar

Of course, once the classloader has found the class it is looking for, it looks no further. So classes with the same name later in the order won't get loaded.

The complication is that the web container has one classloader for each webapp, and these classloaders delegate to other classloaders that manage the common classes. In practice, this means that some classes will only ever be loaded once for the entire container (e.g. 1. and 2.) and others may get loaded multiple times by different classloaders.

(When a class is loaded more than once, it results in distinct Class objects and distinct class statics. The versions of the class are different types as far as the JVM is concerned and you cannot typecast from one version to the other.)

Finally, Tomcat can be configure to allow individual webapps to be "hot loaded". This entails stopping a webapp, creating a new classloader for it, and restarting it.

FOLLOWUP

So ... synchronizing a static method will not protect access to a shared resource where the class has been loaded multiple times?

It depends on the details, but it probably won't. (Or to look at if another way, if a class has actually been loaded multiple times, then a static method of each "load" of the class will access a different set of static fields.)

If you really want a singleton application class instance to be shared by multiple webapps in the same container, it is simplest if you put the class into $CATALINA_HOME/lib or the equivalent. But you also should ask yourself if this is good system design. Consider combining the webapps, or to using request forwarding etc instead of a shared data structure. The singleton pattern tends to be troublesome in webapps, and this flavor is even more so.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

ClassCastException when loading same Class from two different wars in same ear, due to different class loaders

how to add class when multiple class exists with same name

Check if method exists in the same class

Class With The Same Name Already Exists

Java - how to load different versions of the same class?

Java - how to load different versions of the same class?

How to run the same AsyncTask class for different processes?

How to reference a class in a different package in the same project

How to wrapAll element with the same class but different position

import static does not work when the class has methods with the same name as the imported ones

Why does not transition work when removing and adding the class to the same element using removeClass() and addClass()?

Passing class to constructor, when no such constructor exists. Why does it work?

how can I design a class with one variable and still work with different variables at the same time?

Code doesn't run when instancing multiple objects from the same class, but does work when instancing objects from a duplicate class with the same code

How to use Laravel eager loading on model that belongsTo same class

Same class name in different packages

Different JSON serialization for the same class

Same class variables in different instances?

Register same class for different types

target same class different id

Does different instances share the same methods declared in the class?

Does serialization of objects with same class but different packages cause an errors in Axon?

getClass() can not work the same as .class

Why does == and === equality seem to work the same for UIView class?

Why the class button does not work the same as the kv file button?

How to run different Methods of same class in different threads?

Kotlin - same class, different internal class

Scrape data using R when div class is different for the same attribute

Same hierarchy, different behaviour when accessing protected member of base class