Подтвердить что ты не робот

GetResourceAsStream не загружает ресурс в webapp

У меня есть веб-приложение, которое использует библиотеку, которая находится в TOMCAT_HOME/common/lib. Эта библиотека ищет файл свойств в корневой части пути к классам (в классе ApplicationConfig):

ApplicationConfig.class.getResourceAsStream("/hv-application.properties");

Мое приложение Tomcat содержит этот файл свойств. Это в WEB-INF/classes, который является корнем пути к классу? Однако во время выполнения, когда он пытается загрузить файл свойств, он выдает исключение, потому что он не может его найти (getResourceAsStream возвращает null).

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

4b9b3361

Ответ 1

Попробуйте Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties").

Ответ 2

Похоже, это может быть связано с тем, как работают загрузчики классов Tomcat. Если у вас есть что-то в одном загрузчике класса (ваш файл конфигурации в загрузчике классов webapp), который используется чем-то в другом (jar common/lib), результат может быть большой головной болью.

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

  • Переместите файл jar в общий /lib в ваше веб-приложение (WEB-INF/lib). Это не всегда возможно, я знаю, но иногда баночки (например, log4j) могут мирно сосуществовать между загрузчиками классов (*).
  • Переместите файл конфигурации в общий/класс. Это фактически то же самое (помещает элемент конфигурации в тот же загрузчик классов, что и его баночка). Опять же, это не идеально, но если вы контролируете свою среду, это сработает.

В любом случае наличие ресурсов в разных загрузчиках классов может быть больно. Надеюсь, это поможет.

(*) log4j имеет параметр -log4j.ignoreTCL, который делает это возможным, хотя

Ответ 3

Менеджер безопасности Tomcat обычно не позволит вам получать доступ к классам и ресурсам Webapp из библиотек в корневых библиотеках Tomcat. Это предназначено для разделения между веб-приложениями, запущенными в контейнере.

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

Ответ 4

Я расширяю комментарий Olivier в качестве ответа (спасибо вам за лидерство).

Проблема кажется ведущей косой чертой (/) в пути ресурса.

В Tomcat 8 WebAppClassloader правильно решает путь с и без косой черты. Оба .getResourceAsStream("/org/pakopa/app/config.properties"); и .getResourceAsStream("org/pakopa/app/config.properties"); возвращают InputStream.

В Tomcat 7 (И я тоже предполагаю, что предыдущие версии) .getResourceAsStream("/org/pakopa/app/config.properties"); не разрешен и возвращает null, но .getResourceAsStream("org/pakopa/app/config.properties"); правильно разрешен.