SpringBootMavenPlugin打包异常解决⽅案
【背景】spring-boot项⽬,打包成可执⾏jar,项⽬内有两个带有main⽅法的类并且都使⽤了@SpringBootApplication注解(或者另⼀种情形:你有两个main⽅法并且所在类都没有使⽤@SpringBootApplication注解),l如下
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
【问题】
执⾏mvn clean package,报错如下(说点不相关的,使⽤install同理。因为spring-boot:repackage⽬标(goal)(下⽂会说)被绑定在package构建阶段(phases),⽽package阶段在install阶段之前,指定构建阶段之前的阶段都会执⾏。详细参见:)
  [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.3.RELEASE:repackage (default) on project webapps-api-bid: Execution default of goal org.springframework.boot:spring-boot-maven-
plugin:1.5.3.RELEASE:repackage failed: Unable to find a single main class from the following candidates
[api.main.ApiBidMain, webapps.api.main.WebappsApiBidMain]
执⾏mvn clean package spring-boot:repackage,报错如下,不如上⾯⽇志详细
  [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.3.RELEASE:repackage (default) on project webapps-api-bid: Execution default of goal org.springframework.boot:spring-boot-maven-
plugin:1.5.3.RELEASE:repackage failed: Unable to find main class
【解决】
  Note:参考,没有指定<mainClass>或者继承了spring-boot-starter-parent并且<start-class>属性未配置时,会⾃动寻签名是public static void main(String[] args)的⽅法... 所以插件懵逼了,两个妹⼦和谁在⼀起呢...
[推荐] 通⽤解决⽅法:<configuration>下配置mainClass,指定程序⼊⼝。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.3.RELEASE</version>
<configuration>
<mainClass&webapps.api.main.WebappsApiBidMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
  Spring Boot Maven Plugin提供了⼏个⽬标(goal),我们在<executions>标签⾥配置的<goal>repackage</goal>对应spring-boot:repackage这个⽬标。
repackage: create a jar or war file that is auto-executable. It can replace the regular artifact or can be attached to the build lifecyle with a separate classifier.
run: run your Spring Boot application with several options to pass parameters to it.
start and stop: integrate your Spring Boot application to the integration-test phase so that the application starts before it.  The plugin rewrites your manifest, and in particular it manages theMain-ClassandStart-Classentries, so if the defaults don't work you have to configure those there (not in the jar plugin). TheMain-Classin the manifest is actually controlled by thelayoutproperty of the boot plugin
  [译] 该插件重写了清单⽂件(MANIFEST.MF,也就是jar⾥⾯的清单⽂件),此⽂件管理着主类(Main-Class)和开始类(Start-Class)⼊⼝。清单⽂件中的Main-Class由layout控制
springframework jar包下载
  这⾥的Start-Class就是我们配置的<mainClass>,⽽Main-Class受layout属性的控制,别被名字搞乱了(是不是很诡异?看看解决⽅法⼆就明⽩为啥如此诡异了).... 来张图直观的感受下,对应使⽤上⾯xml配置打包后的清单⽂件
(MANIFEST.MF):
  layout属性默认不需要配置,插件会⾃动推断。不同的layout属性清单⽂件⾥⾯的Main-Class也会相应的不同。⽐如layout不配置或者配置为JAR对应的Main-Class是JarLauncher,layout配置为WAR对应的Main-Class是WarLauncher。[有限制条件]解决⽅法⼆:如果你的pom继承⾃spring-boot-starter-parent(注意此前提),也可以直接在<properties>配置
<start-class>(其实这⾥的start-class直接对应清单⽂件⾥的Start-Class):
<properties>
<start-class&webapps.api.main.WebappsApiBidMain</start-class>
</properties>
解决⽅法三:打包的的时候注释掉其他的@ 或者你有两处main⽅法并且都没有使⽤
@SpringBootApplication注解,注释掉⼀个main⽅法..... 这就是第三种解决⽅法233333
【随便说说】
  说说spring-boot:repackage这个⽬标。Spring Boot Maven Plugin这个插件包含⼀系列⽬标(goal),我们在
<executions>标签⾥配置的<goal>repackage</goal>对应spring-boot:repackage这个⽬标,看下:
  spring-boot:repackage repackages your jar/war to be executable.
  Repackages existing JAR and WAR archives so that they can be executed from the command line using java -jar. Withlayout=NONEcan also be used simply to package a JAR with nested dependencies (and no main class, so not executable).
  简单点说,这货重新打包个可执⾏的jar/war,可以在命令⾏使⽤-jar执⾏。如果指定layout为NONE那就没有主类只是打个普通的jar(不可执⾏),⼀般不会这么做。
  ⼀般情况,这个⽬标会打⼀个新的jar/war,并把maven默认打的jar/war添加.original后缀,在target⽬录下可以看到:
【参考】
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。