53

I have two applications under tomcat/webapps folder.

tomcat/webapps/App1
tomcat/webapps/App2

Both applications share the same libraries. Which are stored for example in tomcat/webapps/App1/WEB-INF/lib.

Are both libraries loaded twice in memory?

Should I put these shared libraries in tomcat/server/lib?

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Sergio del Amo
  • 76,835
  • 68
  • 152
  • 179

6 Answers6

43

As you can see here, Tomcat creates one class-loader per webapp on your server. Thus, if you have webapp1 and webapp2 that share the same library, then this library will be indeed loaded twice.

You can eventually place this library in the common directory (tomcat-dir/common/lib) if it is shared by all webapps that run on your Tomcat server.

Romain Linsolas
  • 79,475
  • 49
  • 202
  • 273
  • 1
    i do not have a common directory inside server, I just have classes and lib directory. Should i create one common inside? – Sergio del Amo Nov 06 '08 at 08:45
  • I edited my post to indicate that the good directory to use is [tomcat-installation-directory]/common/lib – Romain Linsolas Nov 06 '08 at 10:14
  • apparently it's ok [and recommended] to deploy jdbc drivers to shared FWIW http://stackoverflow.com/questions/6981564/why-jdbc-driver-must-been-put-in-tomcat-home-lib-folder] – rogerdpack Sep 26 '14 at 18:01
  • 1
    **Update:** In more recent versions of Tomcat, there is no "common" folder bundled by default. The "Common" class loader is now configured in the `catalina.properties` file to use a folder named `lib` in either the "base" or "home" folders of Tomcat. Furthermore, as you can see in `catalina.properties` both the "Server" class loader and the "Shared" class loader use the same, the `lib` folder in "base" or "home". If you want separate folders, create the folders, then point Tomcat in that direction by editing `catalina.properties`. – Basil Bourque Oct 15 '19 at 23:50
29

I wouldn't recommend placing the jar files in the shared folder. Let's say for example that you need in the future to deploy a third party application, that has a newer version of a jar file in the WEB-INF folder. For this application the classes of the jar will be loaded twice (even if they have the same names), one from the shared folder and one from the web app folder. This situation may cause bugs very difficult to find.

If the jar files are in the web app folders, then they are loaded by separate class loaders and don't interfere with each other.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
  • 1
    I quite agree. Placing libraries in commons directory can be dangerous, and must be used only if you can control which webapps are deployed, and what are the version of libraries used for each webapp... – Romain Linsolas Nov 06 '08 at 10:15
  • Could you elaborate on being loaded twice? Would the shared ones "override" the ones in the WEB-INF folder? – rogerdpack Sep 26 '14 at 16:56
  • It is better to treat this situation as "undefined". You would have two instances of the same class, each loaded by a different class loader. This usually means problems. – kgiannakakis Sep 29 '14 at 06:49
  • @rogerdpack: There are rules for how this works, but they are complex, and most importantly depend on exactly how the class is loaded (which in turn depends on Tomcat config and Tomcat version). So in practice it's probably better to treat it as "undefined", as kgiannakakis points out. – sleske Feb 05 '15 at 14:29
  • can anyone tell me about the memory consumption because if you load the jars for each folder it will take lots of extra memory. can anyone share their thoughts about it – mayank agrawal Dec 04 '15 at 05:20
8

From experience: the two web-apps are entirely isolated from one another - the libraries for one are not utilised in another - thus to answer your initial question - yes they would be loaded twice.

To answer you second question, whether you should deploy these libraries into Tomcat's shared directory - I would say no, and here's why:

If you deploy a library Jar into the shared location (tomcat/server/lib), then that version of the library becomes the default for all web-applications running under that instance of Tomcat. As you can see from this overview of the tomcat architecture, the class-loader works "down the chain", with an individual web-app's lib folder being the last place it will look before it throws a class-not-found exception. This is not true in Tomcat 6 and Tomcat 7: any classes in the web apps lib and classes folder will be resolved before those in common, and thus, this will not break other apps which deploy all of their jars in the war 2.

The problem therefore of deploying a shared library to that directory is that it breaks the architecture for individual applications being isolated from one-another. Fine in your initial example, but if you want to deploy a third-party application (e.g. if you a running an app that consumes Portlet's to handle specific content), you instantly run in to version dependency issues - your shared version of a library may not be correct for the third-party application, but because the package is already loaded, you'll throw exceptions left right and centre.

steve_ash
  • 1,184
  • 1
  • 10
  • 16
Ian
  • 4,208
  • 21
  • 33
6

We are using tomcat6 and find a good way to have tomcat stuffed with common libraries all our webapps need.

Edit in conf/catalina.properties the entry common.loader. E.g. append an additional folder with jars you like to share 'mylibs'

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,
              ${catalina.home}/lib,${catalina.home}/lib/*.jar,
              {catalina.home}/mylibs/*.jar

Then put all the common libraries there. Done.

Why did we start using a mylibs folder instead of the WEB-INF/lib in all webapps (WAR files)?

Deployment started to be a nightmare after the WAR crossed the 50MB line!

When having a webapp with a never jar version you still can put it into WEB-INF/lib to overwrite what you have in mylibs.

Toni Bünter
  • 93
  • 1
  • 6
4

If you do not want your libraries to load twice put them in:

  • Tomcat 6: $CATALINA_HOME/lib
  • Tomcat 5: $CATALINA_HOME/common/lib

(removed from the question and copied here so it can be voted/commented on)

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
  • 1
    You can also customize catalina.properties to add your own custom directory to the common class loader. This is helpful to segregate Tomcat jars with jars needed by your applications. – JustinKSU Apr 21 '17 at 14:06
  • 2
    I would not recommend this -- you should not mix your custom files together with the stock files, because it will not be clear which ones are yours when someone new comes along in the future. – Kevin Panko Apr 26 '17 at 14:54
0

PermGen Space of heap is used to store classes and Meta data about classes in Java.

Error java.lang.OutOfMemoryError: PermGen space can occurred frequently because we are loading lots of duplicate library in apache tomcat can anyone share about it in details

mayank agrawal
  • 628
  • 5
  • 20