Spring Boot Maven Plugin打包異常解決方案
【背景】spring-boot項(xiàng)目,打包成可執(zhí)行jar,項(xiàng)目?jī)?nèi)有兩個(gè)帶有main方法的類并且都使用了@SpringBootApplication注解(或者另一種情形:你有兩個(gè)main方法并且所在類都沒(méi)有使用@SpringBootApplication注解),pom.xml如下
<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>
【問(wèn)題】
執(zhí)行mvn clean package,報(bào)錯(cuò)如下(說(shuō)點(diǎn)不相關(guān)的,使用install同理。因?yàn)閟pring-boot:repackage目標(biāo)(goal)(下文會(huì)說(shuō))被綁定在package構(gòu)建階段(phases),而package階段在install階段之前,指定構(gòu)建階段之前的階段都會(huì)執(zhí)行。詳細(xì)參見(jiàn):Introduction to the Build Lifecycle)
[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 [com.xx.api.main.ApiBidMain, com.xx.webapps.api.main.WebappsApiBidMain]
執(zhí)行mvn clean package spring-boot:repackage,報(bào)錯(cuò)如下,不如上面日志詳細(xì)
[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:參考官網(wǎng)描述,沒(méi)有指定<mainClass>或者繼承了spring-boot-starter-parent并且<start-class>屬性未配置時(shí),會(huì)自動(dòng)尋找簽名是public static void main(String[] args)的方法... 所以插件懵逼了,兩個(gè)妹子和誰(shuí)在一起呢...
[推薦] 通用解決方法:<configuration>下配置mainClass,指定程序入口。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.3.RELEASE</version>
<configuration>
<mainClass>com.xx.webapps.api.main.WebappsApiBidMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Spring Boot Maven Plugin提供了幾個(gè)目標(biāo)(goal),我們?cè)?lt;executions>標(biāo)簽里配置的<goal>repackage</goal>對(duì)應(yīng)spring-boot:repackage這個(gè)目標(biāo)。
- 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控制
這里的Start-Class就是我們配置的<mainClass>,而Main-Class受layout屬性的控制,別被名字搞亂了(是不是很詭異?看看解決方法二就明白為啥如此詭異了).... 來(lái)張圖直觀的感受下,對(duì)應(yīng)使用上面xml配置打包后的清單文件(MANIFEST.MF):

layout屬性默認(rèn)不需要配置,插件會(huì)自動(dòng)推斷。不同的layout屬性清單文件里面的Main-Class也會(huì)相應(yīng)的不同。比如layout不配置或者配置為JAR對(duì)應(yīng)的Main-Class是JarLauncher,layout配置為WAR對(duì)應(yīng)的Main-Class是WarLauncher。
[有限制條件]解決方法二:如果你的pom繼承自spring-boot-starter-parent(注意此前提),也可以直接在<properties>配置<start-class>(其實(shí)這里的start-class直接對(duì)應(yīng)清單文件里的Start-Class):
<properties> <start-class>com.xx.webapps.api.main.WebappsApiBidMain</start-class> </properties>
解決方法三:打包的的時(shí)候注釋掉其他的@SpringBootApplication... 或者你有兩處main方法并且都沒(méi)有使用@SpringBootApplication注解,注釋掉一個(gè)main方法..... 這就是第三種解決方法233333
【隨便說(shuō)說(shuō)】
說(shuō)說(shuō)spring-boot:repackage這個(gè)目標(biāo)。Spring Boot Maven Plugin這個(gè)插件包含一系列目標(biāo)(goal),我們?cè)?lt;executions>標(biāo)簽里配置的<goal>repackage</goal>對(duì)應(yīng)spring-boot:repackage這個(gè)目標(biāo),看下官方介紹:
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).
簡(jiǎn)單點(diǎn)說(shuō),這貨重新打包個(gè)可執(zhí)行的jar/war,可以在命令行使用-jar執(zhí)行。如果指定layout為NONE那就沒(méi)有主類只是打個(gè)普通的jar(不可執(zhí)行),一般不會(huì)這么做。
一般情況,這個(gè)目標(biāo)會(huì)打一個(gè)新的jar/war,并把maven默認(rèn)打的jar/war添加.original后綴,在target目錄下可以看到:

【參考】
1.https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
2.https://docs.spring.io/spring-boot/docs/2.0.0.BUILD-SNAPSHOT/maven-plugin//repackage-mojo.html
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- spring-boot-maven-plugin:打包時(shí)排除provided依賴問(wèn)題
- 基于spring-boot-maven-plugin插件打包lib文件外置的方法(layout模式為ZIP模式)
- springboot實(shí)現(xiàn)maven多模塊和打包部署
- Springboot 使用maven release插件執(zhí)行版本管理及打包操作
- maven?springboot如何將jar包打包到指定目錄
- SpringBoot使用Maven插件進(jìn)行項(xiàng)目打包的方法
- SpringBoot+Maven 多模塊項(xiàng)目的構(gòu)建、運(yùn)行、打包實(shí)戰(zhàn)
- Spring Boot如何獲取maven打包時(shí)間
相關(guān)文章
Java設(shè)計(jì)模式之工廠模式實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之工廠模式實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了工廠模式的分類、原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-12-12
Java 線程池詳解及創(chuàng)建簡(jiǎn)單實(shí)例
這篇文章主要介紹了Java 線程池詳解及創(chuàng)建簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
java實(shí)現(xiàn)簡(jiǎn)單聊天室單人版
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單聊天室的單人版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
springAOP的三種實(shí)現(xiàn)方式示例代碼
這篇文章主要介紹了springAOP的三種實(shí)現(xiàn)方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
java中l(wèi)ambda(函數(shù)式編程)一行解決foreach循環(huán)問(wèn)題
這篇文章主要介紹了java中l(wèi)ambda(函數(shù)式編程)一行解決foreach循環(huán)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java實(shí)現(xiàn)按權(quán)重隨機(jī)數(shù)
這篇文章主要介紹了Java實(shí)現(xiàn)按權(quán)重隨機(jī)數(shù),本文給出了提出問(wèn)題、分析問(wèn)題、解決問(wèn)題三個(gè)步驟,需要的朋友可以參考下2015-04-04
一個(gè)MIDP俄羅斯方塊游戲的設(shè)計(jì)和實(shí)現(xiàn)
一個(gè)MIDP俄羅斯方塊游戲的設(shè)計(jì)和實(shí)現(xiàn)...2006-12-12

