Does Tomcat load the same library file into memory twice if they are in two web apps?

TomcatShared Libraries

Tomcat Problem Overview


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?

Tomcat Solutions


Solution 1 - Tomcat

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.

Solution 2 - Tomcat

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.

Solution 3 - Tomcat

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.

Solution 4 - Tomcat

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.

Solution 5 - Tomcat

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)

Solution 6 - Tomcat

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSergio del AmoView Question on Stackoverflow
Solution 1 - TomcatRomain LinsolasView Answer on Stackoverflow
Solution 2 - TomcatkgiannakakisView Answer on Stackoverflow
Solution 3 - TomcatIanView Answer on Stackoverflow
Solution 4 - TomcatToni BünterView Answer on Stackoverflow
Solution 5 - TomcatKevin PankoView Answer on Stackoverflow
Solution 6 - Tomcatmayank agrawalView Answer on Stackoverflow