I have a problem with the start script that I generate with appassembler-maven-plugin. I have a basic spring-boot application with only one class:
@SpringBootApplication
public class ScriptDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ScriptDemoApplication.class, args);
}
}
and my 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>
I run maven with: mvn package appassembler:assemble
Package and scripts are generated but when I try to run ./target/appassembler/bin/app, I get
Error: Could not find or load main class org.home.sziolkow.ScriptDemoApplication
I tested generated packages and I can start the application without problems with:
java -jar ./target/appassembler/repo/org/home/sziolkow/script-demo/0.0.1-SNAPSHOT/script-demo-0.0.1-SNAPSHOT.jar
You're having this trouble because of the way Spring Boot is repackaging your JAR, in order to make it an executable JAR. From the documentation:
Essentially, the Spring Boot Maven Plugin repackages your JAR and puts your classes inside
BOOT-INF/classes, all the JAR dependencies insideBOOT-INF/lib, and launches itsJarLauncherclass as main class, which will search for classes and JARs at those locations.So you have 2 solutions: do not use Spring Boot to repackage your JAR into an executable JAR, or do not use the Appassembler plugin at all.
Without the Appassembler
Since Spring Boot creates an executable JAR for you, generating scripts with the Appassembler plugin is not necessary. Remove the plugin declaration for
appassembler-maven-pluginand have:The only change with your POM is the addition of the
<mainClass>parameter pointing to your main class, and the removal of theappassembler-maven-plugin. When launchingmvn clean package, you'll be able to launch the generated executable JAR directly with:If the version 0.0.1-SNAPSHOT in the name of the executable is an issue, you can simply set a
<finalName>in your POM:and then the executable JAR will be launched with
java -jar target/script-demo.jar.With the Appassembler
As said before, since Spring Boot
repackagegoal put the classes and JARs inside aBOOT-INFfolder, we need to get rid of that. So remove thespring-boot-maven-pluginplugin declaration, and have in your POM:The difference with your current POM is that the Appassembler is bound to the
packagephase, so that the execution is launched without invokingappassembler:assemble. Then, when runningmvn clean package, you'll be able to start your application using the scripts generated by the Appassembler: