Управление classpath в сервлете

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

6 ответов

Решение

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

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

Это сторонние банки или банки, которые вы разработали?

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 страницы, Class Loader HOW-TO.

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам