web-dev-qa-db-fra.com

Tomcat charge-t-il deux fois le même fichier de bibliothèque en mémoire s'il se trouve dans deux applications Web?

J'ai deux applications dans le dossier Tomcat/webapps

Tomcat/webapps/App1
Tomcat/webapps/App2

Les deux applications partagent les mêmes bibliothèques. Qui sont stockés par exemple dans Tomcat/webapps/App1/WEB-INF/lib.

Les deux bibliothèques sont-elles chargées deux fois en mémoire?

Dois-je mettre ces bibliothèques partagées dans Tomcat/server/lib?

48
Sergio del Amo

Comme vous pouvez le voir ici , Tomcat crée un chargeur de classe par application Web sur votre serveur . Ainsi, si vous avez les applications webapp1 et webapp2 qui partagent la même bibliothèque, cette bibliothèque sera effectivement chargée deux fois.

Vous pouvez éventuellement placer cette bibliothèque dans le répertoire commun (rép-Tomcat/common/lib) si elle est partagée par all applications Web exécutées sur votre serveur Tomcat.

37
Romain Linsolas

Je ne recommanderais pas de placer les fichiers JAR dans le dossier partagé. Supposons, par exemple, que vous ayez besoin à l'avenir de déployer une application tierce dotée d'une version plus récente d'un fichier jar dans le dossier WEB-INF. Pour cette application, les classes du fichier jar seront chargées deux fois (même si elles portent le même nom), l'une du dossier partagé et l'autre du dossier de l'application Web. Cette situation peut causer des bugs très difficiles à trouver.

Si les fichiers JAR se trouvent dans les dossiers de l'application Web, ils sont chargés par des chargeurs de classe distincts et n'interfèrent pas les uns avec les autres.

29
kgiannakakis

Par expérience: les deux applications Web sont entièrement isolées l'une de l'autre - les bibliothèques de l'une ne sont pas utilisées dans une autre - donc pour répondre à votre question initiale - oui, elles seraient chargées deux fois.

Pour répondre à votre deuxième question, devez-vous déployer ces bibliothèques dans le répertoire partagé de Tomcat? Je dirais non et voici pourquoi:

Si vous déployez un fichier Jar de la bibliothèque dans l'emplacement partagé (Tomcat/server/lib), cette version de la bibliothèque devient la valeur par défaut pour toutes les applications Web exécutées sous cette instance de Tomcat. Comme vous pouvez le constater dans cet aperçu de l’architecture Tomcat , le chargeur de classes fonctionne "en bas de la chaîne", le dossier lib d’une application Web individuelle étant le dernier emplacement recherché avant la projection d’un class-not- trouvé exception. Ce n’est pas le cas dans Tomcat 6 et Tomcat 7: les classes des répertoires lib et applications des applications Web seront résolues avant celles en commun. Ainsi, cela ne casse pas les autres applications qui déploient tous leurs fichiers jar dans le répertoire. guerre 2 .

Le problème du déploiement d’une bibliothèque partagée dans ce répertoire réside donc dans le fait qu’elle casse l’architecture des applications individuelles isolées les unes des autres. Très bien dans votre exemple initial, mais si vous souhaitez déployer une application tierce (par exemple, si vous exécutez une application qui utilise un portlet pour gérer un contenu spécifique), vous vous retrouvez immédiatement confronté à des problèmes de dépendance de version - votre version partagée d'une bibliothèque peut pas correct pour l'application tierce, mais comme le paquet est déjà chargé, vous lancerez des exceptions à gauche et au centre.

7
Ian

Nous utilisons Tomcat6 et trouvons un bon moyen d’avoir Tomcat bourré de bibliothèques communes dont toutes nos applications Web ont besoin.

Éditez dans conf/catalina.properties l'entrée common.loader . Par exemple. ajoutez un dossier supplémentaire avec les pots que vous aimez partager 'mylibs'

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

Ensuite, mettez toutes les bibliothèques communes là-bas. Terminé.

Pourquoi avons-nous commencé à utiliser un dossier mylibs au lieu de WEB-INF/lib dans toutes les applications Web (fichiers WAR)? 

Le déploiement a commencé à être un cauchemar après que la guerre a franchi la ligne des 50Mo!

Lorsque vous avez une application Web avec une version jamais jar, vous pouvez toujours la mettre dans WEB-INF/lib pour écraser ce que vous avez dans mylibs .

6
Toni Bünter

Si vous ne voulez pas que vos bibliothèques se chargent deux fois, mettez-les dans: 

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

(retiré de la question et copié ici pour pouvoir être voté/commenté)

2
Kevin Panko

PermGen Space of heap est utilisé pour stocker des classes et des métadonnées sur les classes en Java.

Erreur Java.lang.OutOfMemoryError: L'espace PermGen peut être utilisé fréquemment car nous chargeons de nombreuses bibliothèques dupliquées dans Apache Tomcat Quelqu'un peut-il en parler en détail

0
mayank agrawal