Я считаю, что эта проблема была задана ранее в stackoverflow. И я хотел бы упомянуть, что я пробовал решения, связанные с моими вопросами. Тот, который ближе всего к моей проблеме, был:
Загрузить файл свойств в JAR?.
К сожалению, описанное там решение не сработало для меня. И из-за возраста вопроса, который, как я думал, снова спрашивается, это путь.
Перейдем к описанию моей проблемы.
Поэтому в настоящее время я работаю над проектом библиотеки, который был настроен с помощью maven и создает расширение для текущего проекта Spring AMQP.
Цель здесь - предоставить JAR файл, который может быть включен в другой проект для поддержки определенного способа общения через брокера сообщений.
На этом этапе я реализую параметр конфигурации, позволяющий пользователям настраивать клиента обмена сообщениями по своему вкусу. Но пока я тестировал функциональность этой функции, я столкнулся с проблемой при использовании библиотеки в исполняемом JAR.
Во время работы в рабочем пространстве Eclipse все работает нормально. Но когда я пытаюсь запустить его с моего рабочего стола (как runnable JAR), файл свойств, кажется, нигде не найден.
Просто, чтобы дать краткий обзор установки рабочей области/проектов, как описано выше:
Структура проекта обоих проектов отражает дефолт Maven по умолчанию:
- src/main/java
- java source files
- src/main/resources
- resource files
- src/test/java
- java test files
- src/test/resources
- test resource files
Если файл библиотеки содержит файл default.properties в папке src/main/resources, а проект chatclient - файл custom.properties.
После создания исполняемого JAR файла он имеет в себе следующую структуру.
- com
- junit
- META-INF
- org
- resources
- default.resources
- custom.resources
Я считаю, что файлы ресурсов не должны находиться там. но вместо этого в папке META-INF/maven. После того, как вы попробуете такие вещи, как:
- Добавление папки META-INF в папку src/main/resources и размещение там файлов свойств.
- Добавление файла MANIFEST с Class-Path:. в нем.
- Загрузка файла несколькими способами в коде.
Но ничего не работает. Я предполагаю, что это связано с Maven, и простое изменение в pom.xml может исправить это. К сожалению, мои знания о настройке проекта Maven и связанных с ним предметах очень просты (это мой первый проект с использованием maven). И я не могу найти документацию на нем, хотя я знаю, что она должна быть там (вероятно, проблема, вызванная мной).
Прежде чем забыть упомянуть об этом. Я загружаю файлы свойств следующим образом:
Properties props = new Properties();
prop.load(<custom static class>.class.getResourceAsStream(filename));
return props;
Также pom.xml для моей библиотеки выглядит так:
-- Artifact stuff --
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
-- Dependency stuff --
И тот, который для проекта, использующего библиотеку, выглядит следующим образом:
-- Artifact stuff --
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.maxxton</groupId>
<artifactId>async-amqp-messaging</artifactId>
<version>0.2</version>
</dependency>
</dependencies>
-- Other stuff --
Я надеюсь, что есть кто-то, кто немного продвинулся по этому вопросу и может помочь найти решение этой проблемы. И если вам нужна дополнительная информация о файлах/структуре проекта, пожалуйста, дайте мне знать. Я бы с удовольствием поделился им с вами.
Обновление (28-04-2015 {1})
Для тестирования я создал образец проекта, который пытается загрузить файлы свойств так же, как описанный выше сценарий. Даже после выполнения документации Maven (используя папку META-INF) я не смог загрузить свойства.
Для этого вопроса я загрузил рабочую область тестирования здесь.
Я надеюсь, что кто-то может помочь мне исправить это, поскольку нормальный способ, описанный на веб-сайте Maven, кажется, не работает для меня.
Обновление (28-04-2015 {2})
Ну, мне удалось исправить часть проблемы. Поскольку я добавил конфигурацию для maven-assembly-plugin (создание runnable JAR с deps), я смог получить правильную структуру в моем JAR файле. Я добавил:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>project</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.test.project.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Затем при запуске чистой сборки компиляции: single мне удалось получить нужную структуру.
JAR root
- com
- META-INF
- MANIFEST.MF
- default.properties
- custom.properties
Хотя это исправляет часть проблемы. Загрузка файла по-прежнему приводит к исключению NullPointerException.
Окончательное обновление (04-05-2015)
После долгой борьбы Maven мне удалось получить все, как я хочу. Следуя советам, данным как @Deepak, так и @Joop Eggen, я провел некоторое исследование о том, как иметь все зависимости в папке lib как jar, а не распаковывать их в банке uber. Попробовав множество вещей, я наткнулся на этот ответ. Следуя инструкции, создается такая структура:
- runnable.jar
- lib
- spring-amqp.jar
- spring-core.jar
...
При выполнении рекомендаций @Joop Eggen мне удалось загрузить свойство так, как я хочу. Поэтому, похоже, на этот вопрос был дан ответ. В настоящее время я все еще выясняю, как присуждать каждый ответ, поскольку я не могу разделить награду на две части. Я вернусь к этому.
Боковое примечание
Хотя я наградил как щедрость, так и ответ на @Joop Eggen, не означает, что ответ @Deepak не помог. Это дало отличную информацию о лучшей практике, но не было столь полным, как принятый ответ. Поэтому, пожалуйста, найдя свой ответ, дайте ему тоже часть кредита.