Spring Boot добавляет файлы в classpath из командной строки
Я использую Netbeans 8.2 для разработки приложений Spring. Это конкретное приложение, с которым у меня возникают проблемы, - это приложение Spring Boot 1.5.3. У меня есть весенний XML-файл и application.properties, которые я храню в / config в корневом каталоге проекта.
Я передаю весенний XML-файл в свой проект через @ImportResource
аннотация и значение свойства, как @ImportResource(value="${config.xmlfile}")
,
Когда я нажимаю кнопку "Выполнить проект" в Netbeans, запускается мое приложение Spring, и оно корректно находит файл application.properties в моей папке / config. Однако любые ссылки на пути к классам других файлов в этой папке будут потеряны. Например, установка файла config.xml в classpath:config/file.xml
или же classpath:file.xml
оба не могут найти файл, но file:config/file.xml
работает.
Аналогично, при запуске из командной строки в качестве структуры используется следующее:
app/
|-- bin
| `-- app-run.sh
|-- config
| |-- application.properties
| |-- log4j2.xml
| |-- file.xml
`-- app-exec.jar
Я использую spring-boot-maven-plugin
сделать банку следующим образом:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
и мой скрипт app-run.sh выполняет следующее:
exec /bin/java -cp :.:../config/*:../app-exec.jar
-Dlogging.config=../config/log4j2.xml
-Dspring.config.location=../config/application.properties
-jar ../app-exec.jar
где /bin/java представляет место, где я установил Java. Заданный в -cp путь к классам здесь не работает. Подобно тому, как при запуске через IDE, для файла config.xml, устанавливающего для classpath:config/file.xml или classpath:file.xml, оба файла не удается найти файл, но файл:../config/file.xml работает.
Я хотел бы иметь возможность установить classpath как в среде IDE, так и из командной строки, чтобы я мог получить доступ к файлам в Spring с помощью ссылки на classpath, чтобы упростить задачу. Я не хочу помещать их всех в src/main/resources
и пусть они будут упакованы в банку, так как мне нужно редактировать их после упаковки и развертывания.
У кого-нибудь есть идеи или полезные советы? Заранее спасибо!
2 ответа
Обновленный ответ:
Вы можете следовать этой практике в моем первоначальном ответе, но недавно мы отказались от него для более простого и понятного варианта, который является более стандартным (способ "Java"). Мы внесли изменения, потому что нам нужно было динамически загружать зависимые библиотеки во время выполнения, которые были недоступны во время компиляции (в их точной версии). В нашем случае мы хотели загружать зависимые файлы jar только из отдельных папок, а не из исполняемого файла jar. В результате мы получили дублирующиеся зависимости в исполняемых jar-файлах и в отдельных папках, поэтому мы решили удалить исполняемый файл jar Properties Launcher и вместо этого загружать зависимости только из отдельных папок. Это часто НЕ лучший вариант и должен быть оценен для вашего варианта использования. Я предпочитаю читать стандартный Java classpath.
Чтобы запустить приложение Spring Boot без исполняемого файла jar, мы использовали Maven Assembly, чтобы поместить зависимые файлы jar в каталог / libs, и удалили плагин spring-boot-maven-plugin. Шаги и некоторый код для этого ниже:
- Удалите spring-boot-maven-plugin, который создает исполняемый файл jar в формате ZIP
Добавьте следующее в вашу сборку XML
<dependencySets> <dependencySet> <outputDirectory>where you want the libs to go</outputDirectory> <useProjectArtifact>whether you want to include the project artifact here</useProjectArtifact> </dependencySet> </dependencySets>
Запустите свой код из основного класса и включите зависимые папки jar в путь к классам. Используйте стандартную запись classpath в вашей ОС, а не нестандартный, неуклюжий синтаксис пути загрузчика PropertiesLauncher.
java -cp <standard-classpath> <main-class>
Пример фактического звонка: java -cp $CLASSPATH:./lib/*:./cfg/*:my-app.jar Application.class
Таким образом, вы запускаете приложение Spring Boot через стандартный вызов выполнения Java, без специального синтаксиса загрузки Spring. Вам просто нужно убедиться, что все ваши зависимости доступны на пути к классам во время выполнения. Мы обнаружили, что это намного легче поддерживать, и сделали это стандартом для всех наших приложений.
Оригинальный ответ:
После некоторых исследований и благодаря полезному ответу @TuyenNguyen я смог получить следующую работу:
Я добавил следующее в мой spring-boot-maven-plugin, чтобы при запуске из командной строки он использовал PropertiesLauncher
вместо JarLauncher
:
<configuration>
<mainClass>${mainClass}</mainClass>
<layout>ZIP</layout> //THIS IS THE IMPORTANT PART
</configuration>
Смотрите здесь и здесь для получения дополнительной информации о PropertiesLauncher
опции. Это позволяет вам устанавливать путь к классам, между прочим. Смотрите здесь, здесь и здесь, где я нашел ответ на эту проблему. Использование формата ZIP делает PropertiesLauncher
использоваться.
Оттуда я смог использовать эту команду для запуска приложения, как я и предполагал:
java -Dloader.path=../config,../ -Dloader.config.location=classpath:application.properties -jar ../app-exec.jar
Еще одно важное замечание: при указании -Dloader.path
убедитесь, что вы используете значения, разделенные запятыми, и только каталоги и файлы, как описано здесь. Кроме того, обязательно указывайте аргументы -D, прежде чем указывать -jar jar, иначе они не будут установлены.
Если у кого-либо есть какие-либо предложения или изменения для дальнейшего улучшения этого ответа или исходного вопроса, чтобы помочь другим пользователям, пожалуйста, дайте мне знать или внесите изменения самостоятельно!
Если вы не положите свои файлы в src/main/resources
затем вы можете поместить его в любую папку, которую хотите, НО вы должны установить свою папку как папку ресурсов. Так как classpath
всегда указывает на папку ресурсов. Как только вы сделаете вашу папку как папку ресурсов, она будет упакована в банку. Если вы хотите отредактировать файл ресурсов, просто используйте инструмент 7 zip, чтобы открыть ваш jar -> edit files -> save ->, он обновит ваши изменения в jar.
Другое решение - создать папку, поместить все файлы, которые вы хотите отредактировать, и не упаковывать в них, а затем вручную указывать classpath для этой папки при каждом запуске, но способ, указанный выше, неверен, попробуйте это решение для установки правильного пути к classpath.,