Script generated via appassembler-maven-plugin is not able to find main class in Spring Boot application

余生长醉 提交于 2019-12-04 18:07:26

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:

The executable archive cannot be used as a dependency as the exectuable jar format packages application classes in BOOT-INF/classes. This means that they cannot be found when the executable jar is used as a dependency.

Essentially, the Spring Boot Maven Plugin repackages your JAR and puts your classes inside BOOT-INF/classes, all the JAR dependencies inside BOOT-INF/lib, and launches its JarLauncher class 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-plugin and have:

<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>

The only change with your POM is the addition of the <mainClass> parameter pointing to your main class, and the removal of the appassembler-maven-plugin. When launching mvn clean package, you'll be able to launch the generated executable JAR directly with:

java -jar target/script-demo-0.0.1-SNAPSHOT.jar

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:

<build>
  <finalName>${project.artifactId}</finalName>
  <!-- ... -->
</build>

and then the executable JAR will be launched with java -jar target/script-demo.jar.

With the Appassembler

As said before, since Spring Boot repackage goal put the classes and JARs inside a BOOT-INF folder, we need to get rid of that. So remove the spring-boot-maven-plugin plugin declaration, and have in your 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>

The difference with your current POM is that the Appassembler is bound to the package phase, so that the execution is launched without invoking appassembler:assemble. Then, when running mvn clean package, you'll be able to start your application using the scripts generated by the Appassembler:

./target/appassembler/bin/app
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!