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

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

6 ответов


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

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

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


Tomcat 8.5

То Же Самое Tomcat 8.0.

посмотреть документацию: загрузчик класса HOW-TO.

Tomcat 8.0

ответ прост, взятый со страницы документации Tomcat,загрузчик класса 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

мы весной Log4jConfigListener в нашей сети.XML-файл.

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

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


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

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

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


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

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


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

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