Управление classpath в сервлете - PullRequest
6 голосов
/ 05 ноября 2008

В моём приложении сервлетов есть несколько библиотек .jars, некоторые из которых содержат встроенные файлы log4j.xml или log4j.properties. Я хотел бы убедиться, что log4j сначала найдет мой log4j.xml! Я попытался найти некоторую спецификацию приоритетов различных элементов classpath в сервлете (например, всегда ли WEB-INF / классы предшествуют WEB-INF / lib?) Или какой-то способ настроить или настроить загрузчик классов сервлета так, данный каталог ресурсов появляется в начале пути к классам. Пока что я нарисовал бланк. Любые предложения по обеспечению того, чтобы файл .war сервлета загружал правильный log4j.xml через загрузчик классов?

Ответы [ 6 ]

15 голосов
/ 05 ноября 2008

Tomcat 8,5

То же Tomcat 8.0.

См. Документацию: Class Loader HOW-TO .

Tomcat 8.0

Ответ прост, взят из страницы документации Tomcat, Class Loader HOW-TO . Обратите особое внимание на использование каталога / папки /WEB-INF/.

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

  • Классы начальной загрузки вашей JVM
  • /WEB-INF/classes вашего веб-приложения
  • /WEB-INF/lib/*.jar вашего веб-приложения
  • Классы загрузчика системных классов (описано выше)
  • Общие классы загрузчиков классов (описано выше)

Если загрузчик классов веб-приложения настроен с <Loader delegate="true"/>, то порядок становится:

  • Классы начальной загрузки вашей JVM
  • Системные классы загрузчика классов (описано выше)
  • Общие классы загрузчиков классов (описано выше)
  • /WEB-INF/classes вашего веб-приложения
  • /WEB-INF/lib/*.jar вашего веб-приложения

Tomcat 6

Выдержки из страницы Tomcat 6, Загрузчик классов HOW-TO .

Таким образом, с точки зрения загрузки веб-приложения, класса или ресурса выглядит в следующих репозиториях, в следующем порядке:

  • Начальные классы вашей JVM
  • Классы загрузчика системных классов (описано выше)
  • /WEB-INF/classes вашего веб-приложения
  • /WEB-INF/lib/*.jar вашего веб-приложения
  • $CATALINA_HOME/lib
  • $CATALINA_HOME/lib/*.jar
4 голосов
/ 05 ноября 2008

Насколько я понимаю, выбор ресурса из пути к классам недетерминирован (с точки зрения разработчика приложения). Даже если один и тот же файл загружен последовательно, поведение может измениться: 1. При обновлении версии вашего текущего контейнера. 2. Если вы меняете контейнеры.

Самым простым решением будет удалить встроенные файлы конфигурации log4j из библиотек jar . Практически никогда не стоит внедрять конфигурацию log4j, поскольку это приводит к проблеме, с которой вы здесь сталкиваетесь ...

Это банки других производителей или банки, которые вы разработали?

3 голосов
/ 05 ноября 2008

Мы, Весна Log4jConfigListener в нашем файле web.xml.

Вы можете указать в качестве параметра контекста расположение файла конфигурации log4j, т.е. вы можете установить его как /WEB-INF/log4j.xml

Будет ли это вариант для вас? Если вы не используете Spring, я знаю, что вы можете установить местоположение Log4j программно, что также может сработать.

1 голос
/ 05 ноября 2008

Если вы не можете контролировать путь к классу, поскольку Tomcat устанавливает его для вас, вы хотя бы можете установить системное свойство для log4j.configuration? Я считаю, что местоположение, на которое указывает это свойство, может быть установлено вне пути к классам.

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

1 голос
/ 05 ноября 2008

По моему опыту, WEB-INF / классы обычно имеют приоритет над jar-файлами в WEB-INF / lib, однако это также зависит от используемого вами сервлет-контейнера (например, я никогда не мог понять поведение JRun). Было бы очень полезно, если бы вы могли сказать мне, какой контейнер вы используете.

Кроме того, вы уверены, что конфигурация log4j, вызывающая проблемы, находится в банке в WEB-INF / lib? Обычно, когда я сталкиваюсь с проблемами пути к классам в ситуации с контейнером сервлета, это происходит из-за библиотек, которые находятся вне веб-приложения.

Спецификации сервлета рекомендуют , чтобы загрузчики классов веб-приложения загружали свои собственные классы перед делегированием загрузчику классов контейнера (SRV.9.7.2), но, поскольку это противоречит спецификации Java, не все поставщики делают это по умолчанию (фактически Tomcat - единственный контейнер, который я использовал, который делает это по умолчанию). При этом всегда можно настроить поведение загрузки классов вашего веб-приложения. Если вы сообщите мне, какой контейнер вы используете, я смогу вам помочь (в частности, я успешно делал это раньше в WebLogic, WebSphere, Glassfish и JRun)).

0 голосов
/ 05 ноября 2008

Вам необходимо иметь log4j.properties в вашем CLASSPATH. Лучшее место - под WEB-INF / классами.

Вы также должны убедиться, что используете свою версию log4j.jar. Поэтому поместите его в WEB-INF / lib, просто чтобы убедиться, что вы не используете его из папок tomcat, поскольку это может вызвать странные проблемы с загрузкой классов.

...