Загружает ли Tomcat один и тот же файл библиотеки в память дважды, если они находятся в двух веб-приложениях?
-
06-07-2019 - |
Вопрос
У меня есть два приложения в разделе tomcat/webapps
папка.
tomcat/webapps/App1
tomcat/webapps/App2
Оба приложения совместно используют одни и те же библиотеки.Которые хранятся, например, в tomcat/webapps/App1/WEB-INF/lib
.
Обе библиотеки загружены в память дважды?
Должен ли я поместить эти разделяемые библиотеки в tomcat/server/lib
?
Решение
Как вы можете видеть здесь , Tomcat создает один загрузчик классов на каждое веб-приложение на вашем сервере. Таким образом, если у вас есть webapp1 и webapp2, которые используют одну и ту же библиотеку, эта библиотека действительно будет загружена дважды.
Вы можете в конечном итоге поместить эту библиотеку в общий каталог (tomcat-dir / common / lib), если она используется всеми веб-приложениями, которые работают на вашем сервере Tomcat.
Другие советы
Я бы не рекомендовал размещать файлы JAR в общей папке. Скажем, например, что вам необходимо в будущем развернуть стороннее приложение с более новой версией файла JAR в папке WEB-INF. Для этого приложения классы фляги будут загружены дважды (даже если они имеют одинаковые имена), один из общей папки и один из папки веб-приложения. Такая ситуация может привести к тому, что ошибки будут очень трудно найти.
Если файлы JAR находятся в папках веб-приложения, они загружаются отдельными загрузчиками классов и не мешают друг другу.
Из опыта: два веб-приложения полностью изолированы друг от друга - библиотеки для одного не используются в другом - таким образом, чтобы ответить на ваш первоначальный вопрос - да, они будут загружены дважды.
Чтобы ответить на второй вопрос, следует ли развертывать эти библиотеки в общем каталоге Tomcat - я бы сказал, нет, и вот почему:
Если вы развернете библиотеку Jar в общую папку (tomcat / server / lib), то эта версия библиотеки станет версией по умолчанию для всех веб-приложений, работающих под этим экземпляром Tomcat. Как вы можете видеть из этого обзора архитектуры tomcat , класс Загрузчик работает «по цепочке», при этом папка lib отдельного веб-приложения является последним местом, в котором оно будет искать, прежде чем оно сгенерирует исключение «не найден класс». Это не так в Tomcat 6 и Tomcat 7: любые классы в папке lib веб-приложений и папках классов будут разрешаться раньше, чем общие, и, таким образом, это не сломает другие приложения, которые развертывают все свои банки в войне 2 .
Следовательно, проблема развертывания разделяемой библиотеки в этом каталоге заключается в том, что она нарушает архитектуру для отдельных приложений, изолированных друг от друга. Хорошо в вашем первоначальном примере, но если вы хотите развернуть стороннее приложение (например, если у вас запущено приложение, которое использует портлеты для обработки определенного содержимого), вы сразу же столкнетесь с проблемами зависимости от версии - ваша общая версия библиотеки может не подходит для стороннего приложения, но поскольку пакет уже загружен, вы будете выбрасывать исключения влево и вправо.
Мы используем 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 .
Если вы не хотите, чтобы ваши библиотеки загружались дважды, поместите их в:
- Кот 6:
$CATALINA_HOME/lib
- Кот 5:
$CATALINA_HOME/common/lib
(удалено из вопроса и скопировано здесь, чтобы за него можно было проголосовать / прокомментировать)
Пространство кучи PermGen используется для хранения классов и метаданных о классах в Java.
Ошибка java.lang.OutOfMemoryError: пространство PermGen может возникать часто, потому что мы загружаем много дублирующихся библиотек в apache tomcat Кто-нибудь может рассказать об этом подробнее