Загружает ли Tomcat один и тот же файл библиотеки в память дважды, если они находятся в двух веб-приложениях? - PullRequest
49 голосов
/ 06 ноября 2008

У меня есть два приложения в папке tomcat/webapps.

tomcat/webapps/App1
tomcat/webapps/App2

Оба приложения используют одни и те же библиотеки. Которые хранятся, например, в tomcat/webapps/App1/WEB-INF/lib.

Обе библиотеки загружены дважды в память?

Должен ли я поместить эти общие библиотеки в tomcat/server/lib?

Ответы [ 6 ]

37 голосов
/ 06 ноября 2008

Как вы можете видеть здесь , Tomcat создает один загрузчик классов для каждого веб-приложения на вашем сервере. Таким образом, если у вас есть webapp1 и webapp2, которые совместно используют одну и ту же библиотеку, то эта библиотека действительно будет загружена дважды.

Вы можете в конечном итоге поместить эту библиотеку в общий каталог (tomcat-dir / common / lib), если она совместно используется всеми веб-приложениями, работающими на вашем сервере Tomcat.

29 голосов
/ 06 ноября 2008

Я бы не рекомендовал помещать файлы jar в общую папку. Скажем, например, что вам необходимо в будущем развернуть стороннее приложение с более новой версией файла JAR в папке WEB-INF. Для этого приложения классы фляги будут загружены дважды (даже если они имеют одинаковые имена), один из общей папки и один из папки веб-приложения. Такая ситуация может привести к тому, что ошибки будут очень трудно найти.

Если файлы JAR находятся в папках веб-приложения, они загружаются отдельными загрузчиками классов и не мешают друг другу.

7 голосов
/ 06 ноября 2008

Из опыта: два веб-приложения полностью изолированы друг от друга - библиотеки для одного не используются в другом - таким образом, чтобы ответить на ваш первоначальный вопрос - да, они будут загружены дважды.

Чтобы ответить на ваш второй вопрос, следует ли развертывать эти библиотеки в общем каталоге Tomcat - я бы сказал, нет, и вот почему:

Если вы развернете библиотеку Jar в общую папку (tomcat / server / lib), то эта версия библиотеки станет версией по умолчанию для всех веб-приложений, работающих под этим экземпляром Tomcat. Как вы можете видеть из этого обзора архитектуры tomcat , загрузчик классов работает "по цепочке", при этом папка lib отдельного веб-приложения является последним местом, которое она будет искать перед тем, как выбросит класс. не найденное исключение. Это не относится к Tomcat 6 и Tomcat 7: любые классы в папке lib и классах веб-приложений будут разрешены раньше, чем общие, и, таким образом, это не сломает другие приложения, которые развертывают все свои банки. на войне 2 .

Следовательно, проблема развертывания разделяемой библиотеки в этом каталоге заключается в том, что она нарушает архитектуру для отдельных приложений, изолированных друг от друга. Хорошо в вашем первоначальном примере, но если вы хотите развернуть стороннее приложение (например, если у вас запущено приложение, которое использует портлеты для обработки определенного содержимого), вы сразу же столкнетесь с проблемами зависимости от версии - ваша общая версия библиотеки может не подходит для стороннего приложения, но поскольку пакет уже загружен, вы будете выбрасывать исключения влево и вправо и по центру.

6 голосов
/ 01 июля 2014

Мы используем tomcat6 и находим хороший способ наполнить tomcat общими библиотеками, которые нужны всем нашим веб-приложениям.

Редактировать в conf / catalina.properties запись common.loader . Например. добавьте дополнительную папку с банками, которые вы хотели бы поделиться с mylibs

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

Затем поместите все общие библиотеки туда. Готово.

Почему мы начали использовать папку mylibs вместо WEB-INF / lib во всех веб-приложениях (файлы WAR)?

Развертывание стало кошмаром после того, как WAR пересекла линию 50 МБ!

Если у вас есть веб-приложение с версией, не имеющей фляги, вы все равно можете поместить его в WEB-INF / lib , чтобы перезаписать то, что у вас есть в mylibs .

3 голосов
/ 02 февраля 2015

Если вы не хотите, чтобы ваши библиотеки загружались дважды, введите их:

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

(удалено из вопроса и скопировано здесь, чтобы за него можно было проголосовать / прокомментировать)

0 голосов
/ 04 декабря 2015

Пространство кучи PermGen используется для хранения классов и метаданных о классах в Java.

Ошибка java.lang.OutOfMemoryError: пространство PermGen может возникать часто, потому что мы загружаем много дублирующихся библиотек в Apache Tomcat Кто-нибудь может рассказать об этом подробнее

...