SpringBoot程序打包失敗(.jar中沒有主清單屬性)
最近在學習SpringBoot,打包SpringBoot程序后,在cmd運行出現(xiàn)了 某某某.jar中沒有注清單屬性 。

我當時也是很懵逼,就去萬能的互聯(lián)網(wǎng)尋求幫助,累計找了大概十幾篇文章吧,最后總算是在一個網(wǎng)友的評論中得到了答案,在此先感謝那位留下評論的熱心網(wǎng)友。
我的錯誤
說明一下,我的SpringBoot模板是基于aliyun鏡像創(chuàng)建的。
在默認給出的配置的環(huán)境下,pom.xml中是有spring-boot-maven-plugin這個依賴的,所以可以先排除沒有這個依賴的說法。
我用maven打包后,只給出了一個內(nèi)存較小的jar文件,運行這個文件,就會出現(xiàn)上述沒有主屬性清單的錯誤,至于這個jar文件為何會出現(xiàn)這個錯誤,我會在文章的下面講。
在看到這位熱心網(wǎng)友的評論時,我也不明白是因為什么,根據(jù)TA的說法,我更改的默認的配置,唉,成了,在打包后出現(xiàn)了兩個jar。

運行那個內(nèi)存占用較大的jar,運行成功(喜)。而為什么要運行占用內(nèi)存較大的呢,也在后文做解釋。
解決方法
我的解決方案:
對pom.xml文件做如下修改
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<!-- 把這里給刪除就可以打包成功 -->
<!--<configuration>
<mainClass>com.sun.SSMPApplication</mainClass>
<skip>true</skip>
</configuration>-->
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>錯誤分析
要想搞清楚這個問題就要說說.jar文件的工作機制了,知道了這個東西就知道如何避免此類問題的發(fā)生了。
搞java開發(fā)平時會接觸很多jar包,比如mysql的驅(qū)動jar包,而上面我們打包程序后得到的也是一個jar文件。這個時候如果你使用上面的java -jar指令去執(zhí)行mysql的驅(qū)動jar包就會出現(xiàn)上述不可執(zhí)行的現(xiàn)象。
而SpringBoot項目為什么能執(zhí)行呢?其實是因為打包方式不一樣。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>我們分別開啟這段配置和注釋掉這段配置分別執(zhí)行兩次打包,然后觀察兩次打包后的程序包的差別,共有3處比較明顯的特征:
1、打包后文件的大小不同
2、打包后所包含的內(nèi)容不同
3、打包程序中個別文件內(nèi)容不同
大小不同
先看第一個現(xiàn)象,文件大小不同。帶有配置時打包生成的程序包大小如下:

包含內(nèi)容不同
不難看出,帶有配置的程序包體積比不帶配置的大了30倍,看看里面的內(nèi)容有什么區(qū)別。


發(fā)現(xiàn)內(nèi)容也完全不一樣,僅有一個目錄是一樣的,叫做META-INF。打開容量大的程序包中的BOOT-INF目錄下的classes目錄,發(fā)現(xiàn)其中的內(nèi)容居然和容量小的程序包中的內(nèi)容完全一樣。


原來大的程序包中除了包含小的程序包中的內(nèi)容,還有別的東西?;氐紹OOT-INF目錄下,打開lib目錄,里面顯示了很多個jar文件。

這些jar文件都是我們制作這個工程時導(dǎo)入的坐標對應(yīng)的文件。SpringBoot程序為了讓自己打包生成的程序可以獨立運行,不僅將項目中自己開發(fā)的內(nèi)容進行了打包,還把當前工程運行需要使用的jar包全部打包進來了。這樣做就是為了可以獨立運行。不依賴程序包外部的任何資源可以獨立運行當前程序。這也是為什么大的程序包容量是小的程序包容量的30倍的主要原因。
再看看大程序包還有什么不同之處,在最外層目錄包含一個org目錄,進入此目錄,目錄名是org\springframework\boot\loader,在里面可以找到一個JarLauncher.class的文件。再看這套目錄名,明顯是一個Spring的目錄名。
個別文件內(nèi)容不同
回到兩個程序包的最外層目錄,查看名稱相同的文件夾META-INF下都有一個叫做MANIFEST.MF的文件,但是大小不同,打開文件,比較內(nèi)容區(qū)別
小容量文件的MANIFEST.MF
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Built-By: 名字 Created-By: Apache Maven 3.8.1 Build-Jdk: 1.8.0_201
大容量文件的MANIFEST.MF
Manifest-Version: 1.0 Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx Archiver-Version: Plexus Archiver Built-By: 名字 Spring-Boot-Layers-Index: BOOT-INF/layers.idx Start-Class: com.sun.SSMPApplication Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Spring-Boot-Version: 2.6.13 Created-By: Apache Maven 3.8.1 Build-Jdk: 1.8.0_201 Main-Class: org.springframework.boot.loader.JarLauncher
大文件中明顯比小文件中多了幾行信息,其中最后一行信息是Main-Class: org.springframework.boot.loader.JarLauncher。即如果使用java -jar執(zhí)行此程序包,將執(zhí)行Main-Class屬性配置的類,這個類恰巧就是前面看到的那個文件。原來SpringBoot打包程序中出現(xiàn)Spring框架的東西是為這里服務(wù)的。而這個org.springframework.boot.loader.JarLauncher類內(nèi)部要查找Start-Class屬性中配置的類,并執(zhí)行對應(yīng)的類。這個屬性在當前配置中也存在,對應(yīng)的就是我們的引導(dǎo)類類名。
- SpringBoot程序添加配置后會打出一個特殊的包,包含Spring框架部分功能,原始工程內(nèi)容,原始工程依賴的jar包
- 首先讀取MANIFEST.MF文件中的Main-Class屬性,用來標記執(zhí)行java -jar命令后運行的類
- JarLauncher類執(zhí)行時會找到Start-Class屬性,也就是啟動類類名
- 運行啟動類時會運行當前工程的內(nèi)容
- 運行當前工程時會使用依賴的jar包,從lib目錄中查找
SpringBoot打出來了包為了能夠獨立運行,將所有需要使用的資源全部都添加到了這個包里。這就是為什么這個jar包能獨立運行的原因。
總結(jié)
再來看之前的報錯信息:

由于打包時沒有使用那段配置,結(jié)果打包后形成了一個普通的jar包,在MANIFEST.MF文件中也就沒有了Main-Class對應(yīng)的屬性了,所以運行時提示找不到主清單屬性,這就是報錯的原因。
到此這篇關(guān)于SpringBoot程序打包失敗(.jar中沒有主清單屬性)的文章就介紹到這了,更多相關(guān)SpringBoot程序打包失敗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合Lucene實現(xiàn)全文檢索的詳細步驟
全文搜索(Full-Text?Search)是指對大規(guī)模存儲在計算機系統(tǒng)中的文本數(shù)據(jù)進行檢索和匹配的技術(shù),它允許用戶輸入關(guān)鍵字,然后從海量的文本數(shù)據(jù)中快速找到相關(guān)的信息,本文介紹了SpringBoot整合Lucene實現(xiàn)全文檢索的詳細步驟,需要的朋友可以參考下2024-03-03
Spring Security添加驗證碼的兩種方式小結(jié)
使用spring security的時候,框架會幫我們做賬戶密碼的驗證,但是如我們需要添加一個驗證碼,就需要對配置文件進行修改,這篇文章主要給大家介紹了關(guān)于Spring Security添加驗證碼的兩種方式,需要的朋友可以參考下2021-10-10
基于Java中對域和靜態(tài)方法的訪問不具有多態(tài)性(實例講解)
下面小編就為大家?guī)硪黄贘ava中對域和靜態(tài)方法的訪問不具有多態(tài)性(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
Java中List for循環(huán)的6種寫法總結(jié)(推薦)
下面小編就為大家?guī)硪黄狫ava中List for循環(huán)的6種寫法總結(jié)(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
springboot實現(xiàn)rtsp視頻推流的示例代碼
本文指導(dǎo)通過Docker搭建RTSP服務(wù),配置Maven依賴,創(chuàng)建RtspStreamer類并測試流地址rtsp://localhost:8554/live的實現(xiàn)過程,感興趣的可以了解一下2025-07-07
詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用
這篇文章主要介紹了 log4j.properties配置與加載應(yīng)用的相關(guān)資料,需要的朋友可以參考下2018-02-02
MyBatis?原生二級緩存"難以修復(fù)"的原因解析及解決方案
文章主要討論了MyBatis原生二級緩存存在的問題,包括結(jié)構(gòu)性缺陷、難以修復(fù)等,社區(qū)提供了多種增強插件方案,但這些方案也有各自的優(yōu)缺點,本文結(jié)合實例代碼介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2025-12-12

