Загрузить файл свойств в JAR?

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

static
{
    Properties props = new Properties();
    try 
    {
        props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
    } catch (IOException e) 
    {
        e.printStackTrace();
    }
    someProperty = props.getProperty("someKey");
}

Файл свойств находится в моем каталоге "src/main/resources" проекта Maven. Когда я запускаю этот код из моего теста junit в Eclipse, он выполняется просто отлично. Когда проект построен с Maven в банке и включен как зависимость в моем веб-приложении, он не может найти файл свойств. Я знаю, что файл свойств находится в базовом каталоге зависящего от jar, я не знаю, как это исправить.

Пожалуйста, помогите!

Ответ 1

Проблема в том, что вы используете getSystemResourceAsStream. Используйте просто getResourceAsStream. Загрузка системных ресурсов из системного загрузчика классов, что почти наверняка не является загрузчиком классов, загружаемым вашей банкой при запуске в качестве webapp.

Он работает в Eclipse, потому что при запуске приложения системный загрузчик классов сконфигурирован с вашей банкой как часть своего пути к классам. (Например, java -jar my.jar будет загружать my.jar в загрузчик системного класса.) Это не относится к веб-приложениям - серверы приложений используют сложную загрузку классов для изоляции веб-приложений друг от друга и от внутренних серверов приложений. Например, см. руководство по загрузке класса tomcat и диаграмму используемой иерархии загрузчика классов.

EDIT: обычно вы вызываете getClass(). getResourceAsStream() для извлечения ресурса в пути к классам, но по мере того как вы извлекаете ресурс в статическом инициализаторе, вам нужно явно указать класс, который находится в загрузчике классов вы хотите загрузить. Самый простой подход - использовать класс, содержащий статический инициализатор, например.

[public] class MyClass {
  static
  {
    ...
    props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
  }
}

Ответ 2

Для записи это описано в Как добавить ресурсы в JAR? (показано для модульных тестов, но то же самое относится к "обычный" ресурс):

Чтобы добавить ресурсы в путь к классам ваши модульные тесты, вы следите за тем же как вы делаете для добавления ресурсов в JAR, за исключением каталога, в котором вы размещать ресурсы в ${basedir}/src/test/resources. В этот момент у вас будет проект структура каталога, которая будет выглядеть например:

my-app
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |       `-- mycompany
    |   |           `-- app
    |   |               `-- App.java
    |   `-- resources
    |       `-- META-INF
    |           |-- application.properties
    `-- test
        |-- java
        |   `-- com
        |       `-- mycompany
        |           `-- app
        |               `-- AppTest.java
        `-- resources
            `-- test.properties

В unit test вы можете использовать простой фрагмент кода, как показано ниже: доступ к ресурсу, требуемому для Тестирование:

...

// Retrieve resource
InputStream is = getClass().getResourceAsStream("/test.properties" );

// Do something with the resource

...