Является ли $ CATALINA_HOME / shared / lib реальной функцией в Tomcat? - PullRequest
1 голос
/ 30 сентября 2019

В Apache Tomcat , я видел несколько постов, которые ссылаются на путь $CATALINA_HOME/shared/lib.

Когда я загружаю Tomcat, я не вижу папки shared, вложенной в домашнюю папку Tomcat.

Я вижу путь $CATALINA_HOME/lib, папку lib, вложенную в домашнюю папку Tomcat. Я понимаю, что это правильное место для файлов JAR, которые не следует копировать в «контексты» (веб-приложения) в Tomcat. Драйверы JDBC являются одним из таких важных примеров.

Проблема заключается в том, что Tomcat заполняет эту папку $CATALINA_HOME/lib многими JAR-файлами для собственного использования. Поэтому, ради аккуратности и простоты администрирования, было бы целесообразно иметь другую папку, в которой не было бы ничего, кроме наших добавленных JAR-файлов, отдельно от собственных JAR-файлов Tomcat. Так что я могу понять необходимость чего-то вроде $CATALINA_HOME/shared/lib.

Проблема в том, что:

  • (a) Я не вижу папки shared,
  • (b) Я не могу найти какую-либо документацию о такой папке.

➥ Является ли это shared/lib реальной функцией, и должен ли я создать эту пару папок , вложенных в домашнюю папку Tomcat?

➥ Является ли $CATALINA_HOME/shared/lib недокументированной функцией , возможно, просто взломом, который может исчезнуть в будущих обновлениях?

Я специально прошу Tomcat 9. Но Tomcat 8 все еще широко используется, поэтому ответ там будет полезен для других людей.

1 Ответ

2 голосов
/ 30 сентября 2019

Предостережение: Я не эксперт Tomcat, этот Ответ - всего лишь мое понимание того, как все работает. Я вполне могу ошибаться;пожалуйста поправьте меня.

tl; др

Да, это реальная особенность.

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

diagram of class loaders in Tomcat

Скажите Tomcat использовать эту папку, отредактировав файл catalina.properties, чтобы присвоить значение свойству с именем shared.loader.

Общий загрузчик классов

Вы имеете в виду функцию общего загрузчика Tomcat.

Как вы упомянули, некоторые JAR-файлы, имеющие драйверы JDBC, не должны реплицироваться отдельно для нескольких веб-приложений в экземпляре Tomcat. Эта тема много раз обсуждалась на переполнении стека.

Такие JAR-файлы должны загружаться общим Java Class Loader , а не загрузчиками классов для каждого веб-приложения.

Несколько загрузчиков классов

Как вы можете видеть на диаграмме выше, Tomcat может использовать много разных загрузчиков классов, как объяснено в документе .

Загрузчики классов Bootstrap и System не имеют отношения к нашему обсуждению здесь.

Загрузчик классов Server используется для собственных нужд Tomcat. Это может включать поиск связанных с Realm пользователей в базе данных от вашего имени. В таком случае Tomcat необходим драйвер JDBC для выбранной вами базы данных.

Как видно из диаграммы с Webapp1 & Webapp2, каждое из ваших веб-приложений также получает загрузчик классов. Это держит каждое веб-приложение отдельно, не позволяя им наступать друг другу на ноги. Например, каждое веб-приложение может использовать разные версии каркаса ведения журнала.

Уловка с драйверами JDBC заключается в том, что они совместно используют реестр в едином объекте DriveManager всей JVM. Этот выбор дизайна командой JDBC, к сожалению, противоречит потребностям сервера приложений, такого как Tomcat, использующего загрузчики различных классов. Это обсуждается в Вопросе, Почему драйвер JDBC должен быть помещен в папку TOMCAT_HOME / lib? и во многих других .

Так что лучше всего использовать один JAR-файл для каждого типа драйвера JDBC через загрузчики классов Tomcat. Это означает, что все ваши веб-приложения должны использовать одну и ту же версию драйвера JDBC каждого типа (Postgres, H2, Oracle и т. Д.).

  • Если у вас не включена функция поиска пользователей Realm в Tomcat, то Tomcat может не использовать свою собственную базу данных. Таким образом, вы можете поместить свой драйвер JDBC в загрузчик классов Shared для использования в одном или нескольких веб-приложениях.
  • Если вы включили что-то в Tomcat, для которого нужна ваша база данных, затем поместите этот JAR-файл JDBC в загрузчик класса Common для использования с внутренними компонентами Tomcat и одно или несколько ваших веб-приложений.

Хитрость в том, что по умолчанию Tomcat определяет только загрузчик классов Common. Загрузчик класса Common выполняет двойную функцию в качестве загрузчиков класса Server и Shared. Чтобы активировать отдельные загрузчики классов для Server и / или Shared, отредактируйте файл catalina.properties. Найдите свойства server.loader & shared.loader.

catalina.properties file

Что касается документации, см. Эту основную страницу в руководстве: Инструкции по загрузке классов . Также упоминание в вики-странице .

Эта проблема кратко обсуждается в комментариях, найденных в файле $CATALINA_HOME/conf/catalina.properties. За исключением условий их лицензии Apache 2:

#
# List of comma-separated paths defining the contents of the "shared"
# classloader. Prefixes should be used to define what is the repository type.
# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
# the "common" loader will be used as Catalina's "shared" loader.
# Examples:
#     "foo": Add this folder as a class repository
#     "foo/*.jar": Add all the JARs of the specified folder as class
#                  repositories
#     "foo/bar.jar": Add bar.jar as a class repository
# Please note that for single jars, e.g. bar.jar, you need the URL form
# starting with file:.
#
# Note: Values may be enclosed in double quotes ("...") in case either the
#       ${catalina.base} path or the ${catalina.home} path contains a comma.
#       Because double quotes are used for quoting, the double quote character
#       may not appear in a path.
shared.loader=

Обратите внимание, что значение по умолчанию для этого свойства shared.loader является пустым. Как поясняется в комментариях, Tomcat откажется от использования своего «обычного загрузчика», который загружает JAR-файлы из папки lib в держателе Catalina Home, а также из папки lib в папке Catalina Base (которую некоторые люди определяют какпапка вне папки Tomcat, для удобства администрирования).

Создайте и укажите свою собственную папку JAR

You может назначить любую папку для хранения файлов JAR , к которым Tomcat будет обращаться через ее «общий загрузчик» (при условии, что учетная запись пользователя вашей системы, на которой запущен Tomcat, имеет привилегии файловой системы для этой папки),AFAIK, создание вложенной папки shared/lib - это просто соглашение.

Внутри папки Tomcat

Если вы хотите использовать папку Tomcat для чего-то вроде $CATALINA_HOME/shared/lib:

  1. Создайте пару из shared & lib папки (с соответствующими правами файловой системы).
  2. Отредактируйте $CATALINA_HOME/conf/catalina.properties, чтобы заменить shared.loader= на:shared.loader="${catalina.home}/shared/lib","${catalina.home}/shared/lib/*.jar"

Обратите внимание, как мы использовали двойные кавычки, как указано в приведенных выше комментариях. И мы указали только lib для файлов классов, а также lib/*.jar для файлов JAR.

За пределами папки Tomcat

Если вы один из тех, кто предпочитает хранить ваши веб-приложения в папке вне папки Tomcat, вы определитеcatalina.base быть этой внешней папкой. В таком случае вы, скорее всего, захотите также хранить свои общие JAR-файлы, а не внутри папки Tomcat. Так что вы можете создать свой shared/lib там. Следуя примеру в этих цитируемых комментариях:

  1. Создайте пару папок shared & lib (с надлежащими привилегиями файловой системы) во внешней папке.
  2. Отредактируйте $CATALINA_HOME/conf/catalina.properties, чтобы заменить shared.loader= на:shared.loader="${catalina.base}/shared/lib","${catalina.base}/shared/lib/*.jar"

Обратите внимание, как мы использовали catalina.base вместо catalina.home.

Как внутри , так и вне папки Tomcat.

Вы можете указать просмотр папок /shared/lib как внутри папки Tomcat ("home"), так и вне папки Tomcat. ("base").

Используйте оба .base & .home:

shared.loader="${catalina.base}/shared/lib","${catalina.base}/shared/lib/*.jar","${catalina.home}/shared/lib","${catalina.home}/shared/lib/*.jar"

Если вы используете Maven для управления вашим Java-проектом, вы захотите отредактировать ваш POM-файл, чтобы установить зависимость для вашего конкретного драйвера JDBC . В этом элементе <dependency> вы захотите установить для <scope> значение provided, чтобы избежать объединения копии вашего драйвера JDBC в файл WAR вашего веб-приложения. См. этот ответ .


Эта старая вики-страница Tomcat кратко упоминает эту же технику создания папок shared/lib, а затем редактирование файла catalina.properties для определения значениядля имущества с именем shared.loader.

...