#java #spring #maven #spring-boot #appassembler
#java #spring #maven #spring-boot #appassembler
Вопрос:
У меня проблема со стартовым скриптом, который я генерирую с помощью appassembler-maven-plugin. У меня есть базовое приложение spring-boot только с одним классом:
@SpringBootApplication
public class ScriptDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ScriptDemoApplication.class, args);
}
}
и мой pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.home.sziolkow</groupId>
<artifactId>script-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>script-demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>
repackage
</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<goal>
package
</goal>
<showConsoleWindow>
true
</showConsoleWindow>
<platforms>
<platform>unix</platform>
</platforms>
<programs>
<program>
<mainClass>org.home.sziolkow.ScriptDemoApplication</mainClass>
<id>app</id>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Я запускаю maven с: mvn package appassembler:assemble
Пакет и скрипты генерируются, но когда я пытаюсь запустить ./target/appassembler/bin/app
, я получаю
Ошибка: не удалось найти или загрузить основной класс org.home.sziolkow.ScriptDemoApplication
Я протестировал сгенерированные пакеты, и я могу запустить приложение без проблем с:
java -jar ./target/appassembler/repo/org/home/sziolkow/script-demo/0.0.1-SNAPSHOT/script-demo-0.0.1-SNAPSHOT.jar
Ответ №1:
У вас возникла эта проблема из-за того, что Spring Boot переупаковывает ваш JAR, чтобы сделать его исполняемым JAR. Из документации:
Исполняемый архив не может использоваться в качестве зависимости, поскольку исполняемый формат jar упаковывает классы приложений
BOOT-INF/classes
. Это означает, что они не могут быть найдены, когда исполняемый файл jar используется в качестве зависимости.
По сути, плагин Spring Boot Maven переупаковывает ваш JAR и помещает ваши классы внутрь BOOT-INF/classes
, все зависимости JAR внутри BOOT-INF/lib
, и запускает свой JarLauncher
класс как основной класс, который будет искать классы и банки в этих местах.
Итак, у вас есть 2 решения: не используйте Spring Boot для переупаковки вашего JAR в исполняемый файл JAR или вообще не используйте плагин Appassembler.
Без Appassembler
Поскольку Spring Boot создает для вас исполняемый файл JAR, генерация сценариев с помощью плагина Appassembler не требуется. Удалите объявление плагина для appassembler-maven-plugin
и:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>org.home.sziolkow.ScriptDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Единственное изменение в вашем POM — это добавление <mainClass>
параметра, указывающего на ваш основной класс, и удаление appassembler-maven-plugin
. При запуске mvn clean package
вы сможете запустить сгенерированный исполняемый файл JAR напрямую с помощью:
java -jar target/script-demo-0.0.1-SNAPSHOT.jar
Если проблема с версией 0.0.1-SNAPSHOT в имени исполняемого файла, вы можете просто установить a <finalName>
в своем POM:
<build>
<finalName>${project.artifactId}</finalName>
<!-- ... -->
</build>
и тогда исполняемый файл JAR будет запущен с java -jar target/script-demo.jar
помощью .
С помощью Appassembler
Как было сказано ранее, поскольку repackage
цель Spring Boot помещает классы и банки в BOOT-INF
папку, нам нужно избавиться от этого. Поэтому удалите spring-boot-maven-plugin
объявление плагина и имейте в своем POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>assemble</goal>
</goals>
<phase>package</phase>
<configuration>
<showConsoleWindow>true</showConsoleWindow>
<platforms>
<platform>unix</platform>
</platforms>
<programs>
<program>
<mainClass>org.home.sziolkow.ScriptDemoApplication</mainClass>
<id>app</id>
</program>
</programs>
</configuration>
</execution>
</executions>
</plugin>
Разница с вашим текущим POM заключается в том, что Appassembler привязан к package
фазе, так что выполнение запускается без вызова appassembler:assemble
. Затем, при запуске mvn clean package
, вы сможете запустить свое приложение, используя скрипты, сгенерированные Appassembler:
./target/appassembler/bin/app
Комментарии:
1. Отлично! Это работает. Я решил избавиться от spring-boot-maven-plugin. Спасибо