spring-boot-maven-plugin插件找不到含有main的主类
【背景】
spring-boot項目執行mvn clean package打包時遇到一個問題,報錯如下:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.4.RELEASE:repackage (default) on project behavior-data: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.3.4.RELEASE:repackage failed:Unable to find a single main class from the following candidates [com.xxx.client.BehaviorDataApplication, com.xxx.client.domain.ReportRankDataDomain]BehaviorDataApplication和ReportRankDataDomain類都有自己的main方法,BehaviorDataApplication是主啟動類。看提示明顯和spring-boot-maven-plugin插件打包有關系。
【解決】
這里其實就是spring-boot-maven-plugin插件在repackage時,會去尋找簽名為public static void main(String[] args)的方法,但項目中有多個,所以插件懵逼了,不知道該找哪個。
直接說解決方式
在插件配置里手動配置下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>或者直接把項目中非啟動類里的main方法都去掉,其實一般的springboot項目非啟動類中添加main方法是不規范的。
【原因】
spring-boot-maven-plugin插件repackage的作用是在maven打包后再次打包,打包為一個fat jar,也就是可以通過命令行java -jar執行的jar或者war包。
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 the Main-Class and Start-Class entries, so if the defaults don’t work you have to configure those there (not in the jar plugin). The Main-Class in the manifest is actually controlled by the layout property of the boot plugin
[譯] 該插件重寫了清單文件(MANIFEST.MF,也就是jar里面的清單文件),此文件管理著Main-Class和Start-Class入口。清單文件中的Main-Class由layout控制
這里的Start-Class就是我們配置的<mainClass> </mainClass>,來張圖直觀的感受下,對應使用上面xml配置打包后的清單文件(MANIFEST.MF):
layout屬性對應著是jar包還是war包,比如layout不配置或者配置為JAR對應的Main-Class是JarLauncher,layout配置為WAR對應的Main-Class是WarLauncher(java -jar啟動時先去這個啟動類,然后再去處理項目的啟動類)。
【擴展】
下面具體的談談spring-boot:repackage,它重新打的包有什么不同,或者它如何將一個普通的jar 重新打包為一個可執行的fat jar。
Repackage existing JAR and WAR archives so that they can be executed from the command
line using {@literal java -jar}. With <code>layout=NONE</code> can also be used simply
to package a JAR with nested dependencies (and no main class, so not executable).
spring-boot-maven-plugin將maven打好的普通jar或war,再次進行打包。把之前maven默認打的包名字末尾添加上.original,效果如下:
然后我們分別進包內部去看下,為什么包大小相差這么多,為什么能直接可執行。
先看下maven打的較小的這個包里面是什么
其實就和在Tomcat部署時webapp自動解壓出的文件結構相同。
然后看插件重新打的包:
關于SpringBoot jar可執行原理有很多文章參考,這里不再贅述。
SpringBoot基于jar包啟動核心原理
總結
以上是生活随笔為你收集整理的spring-boot-maven-plugin插件找不到含有main的主类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重要的基础注解@import
- 下一篇: 线程池解析