溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring Boot項(xiàng)目部署到Linux服務(wù)器運(yùn)行報(bào)錯(cuò)怎么解決

發(fā)布時(shí)間:2022-03-02 10:09:13 來(lái)源:億速云 閱讀:709 作者:iii 欄目:web開(kāi)發(fā)

這篇文章主要介紹“Spring Boot項(xiàng)目部署到Linux服務(wù)器運(yùn)行報(bào)錯(cuò)怎么解決”,在日常操作中,相信很多人在Spring Boot項(xiàng)目部署到Linux服務(wù)器運(yùn)行報(bào)錯(cuò)怎么解決問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Spring Boot項(xiàng)目部署到Linux服務(wù)器運(yùn)行報(bào)錯(cuò)怎么解決”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

一 背景

最近在用 Springboot 開(kāi)發(fā)項(xiàng)目 A,引了小伙伴開(kāi)發(fā)的模塊 B,本地起服務(wù),運(yùn)行的好好的,等部署到服務(wù)器上,一運(yùn)行就報(bào)錯(cuò):Caused by: java.lang.ClassNotFoundException。

注:導(dǎo)致該錯(cuò)誤的原因有很多,比如:包沖突、類沖突、包不存在等,我這里只列舉其中一種情況,畢竟坑了我半天的時(shí)間,我覺(jué)得有必要分享出來(lái)。

二 原因

先看一個(gè)詭異的現(xiàn)象吧,我用別的工程 C 引用了同樣的依賴 B,部署到服務(wù)器上,運(yùn)行的好好的,就我這個(gè)工程不行?細(xì)看:

1)工程 C 部署到服務(wù)器上,/app/C-service/lib 下的 jar包是:

B-api-1.0.0-20191224.024308-5.jar
B-dao-1.0.0-20191223.073120-2.jar

2)工程 C 部署到服務(wù)器上,/app/C-service/C-service.jar/META-INF/MANIFEST.MF,掃描路徑是:

lib/B-api-1.0.0-20191224.024308-5.jar
lib/B-dao-1.0.0-20191223.073120-2.jar

而:

1)我的工程 A 部署到服務(wù)器上,/app/A-service/lib 下的 jar包是:

B-api-1.0.0-SNAPSHOT.jar
B-dao-1.0.0-SNAPSHOT.jar

2)我的工程 A 部署到服務(wù)器上,/app/A-service/A-service.jar/META-INF/MANIFEST.MF,掃描路徑是:

lib/B-api-1.0.0-20191224.024308-5.jar
lib/B-dao-1.0.0-20191223.073120-2.jar

發(fā)現(xiàn):MANIFEST.MF 中掃描的 jar 包路徑和實(shí)際解壓出來(lái)的 jar 包名稱不一致(一個(gè)帶時(shí)間戳,一個(gè)是 SNAPSHOT),所以掃描不到 jar 包,導(dǎo)致報(bào)錯(cuò):Caused by: java.lang.ClassNotFoundException。

那么是什么原因構(gòu)成了這樁慘案呢?機(jī)緣巧合:

1.我小伙伴的模塊,deploy 時(shí)用的是 SNAPSHOT,如 1.0.0-SNAPSHOT,我在拉取 jar包時(shí),拉到的是:B-api-1.0.0-20191224.024308-5.jar:

<dependency>
    <groupId>com.xxx.xxx</groupId>
    <artifactId>B-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

2.我的工程 A 本地可以跑,是因?yàn)槟菚r(shí)候我沒(méi)有打包 mvn clean package -Dmaven.test.skip=true,IDEA 本地運(yùn)行項(xiàng)目時(shí) jar 包掃描路徑 和 實(shí)際拉取的 jar 包一致;當(dāng)我打包后,解壓出 A-service.zip 包,本地運(yùn)行同樣會(huì)報(bào)錯(cuò);

3.問(wèn)題在于工程 A 打包前后的區(qū)別,為什么打包后:MANIFEST.MF 和 A-service.zip 解壓后的 lib/ 目錄下的 jar包 名稱不一致?

4.最后通過(guò)比較工程 C 的配置文件和 A 的配置文件,找到不同點(diǎn):A工程的 assembly.xml 中多了一行:<outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>

<dependencySets>
    <dependencySet>
       <outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>
        <useProjectArtifact>false</useProjectArtifact>
        <outputDirectory>lib</outputDirectory>
    </dependencySet>
</dependencySets>

5.把這行去掉,問(wèn)題確實(shí)解決了。但是為什么呢?拉下來(lái)的 jar 包、MANIFEST.MF 中掃描的 jar包帶時(shí)間戳,總覺(jué)得不夠清秀、哪里不對(duì)勁。隨后我以 outputFileNameMapping 為字眼找了下相關(guān)資料,果然找到了另外一位老大哥:<useUniqueVersions>false</useUniqueVersions> ,這行配置是放在工程的 Service 模塊(Application.java 啟動(dòng)類所在模塊)的 pom.xml 中:

<!-- 打包jar文件時(shí),配置manifest文件,加入lib包的jar依賴 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>${main.class}</mainClass>
                <useUniqueVersions>false</useUniqueVersions>
            </manifest>
        </archive>
        <excludes>
            <exclude>*.yml</exclude>
            <exclude>*.properties</exclude>
        </excludes>
    </configuration>
</plugin>

6.解釋:

1)<outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>,作用是在你打包的時(shí)候:lib/ 下的 jar 包可以重命名,比如本來(lái)應(yīng)該是 B-api-1.0.0-20191224.024308-5.jar,通過(guò)這行配置后,jar包被重命名為:B-api-1.0.0-SNAPSHOT.jar;

2)<useUniqueVersions>false</useUniqueVersions>,作用是在你生成 MANIFEST.MF 文件時(shí),lib/ 下的 jar包如果版本是 xxx-SNAPSHOT,要不要帶唯一版本時(shí)間戳,如果你配置為 false(默認(rèn)為 true),那么本來(lái)應(yīng)該是 B-api-1.0.0-20191224.024308-5.jar,通過(guò)這行配置后,jar包被重命名為:B-api-1.0.0-SNAPSHOT.jar;

剛好:

1)工程 C 中 outputFileNameMapping,useUniqueVersions 都沒(méi)配置,使用默認(rèn)值,使得 lib/ 下的 jar包名稱 和 MANIFEST.MF 下的掃描路徑 jar包名稱一致(都帶時(shí)間戳);

2)而我的工程 A,不只從哪里拷貝來(lái)的配置文件,配了 outputFileNameMapping (沒(méi)帶時(shí)間戳),但沒(méi)配置 useUniqueVersions(帶時(shí)間戳),導(dǎo)致不一致;

所以:這兩個(gè)配置,要么都有,要么都沒(méi)有,不然就會(huì)出現(xiàn)不一致,導(dǎo)致報(bào)錯(cuò)。

三 解決

我個(gè)人覺(jué)得,jar 包名稱還是不帶時(shí)間戳更清秀些,所以我推薦 outputFileNameMapping,useUniqueVersions 都配置上,如下:

1.assembly.xml 中添加配置:<outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>

<dependencySets>
    <dependencySet>
        <outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>
        <useProjectArtifact>false</useProjectArtifact>
        <outputDirectory>lib</outputDirectory>
    </dependencySet>
</dependencySets>

2.啟動(dòng)類 Application.java 所在模塊的 pom.xml 中添加配置:<useUniqueVersions>false</useUniqueVersions>

<!-- 打包jar文件時(shí),配置manifest文件,加入lib包的jar依賴 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>${main.class}</mainClass>
                <useUniqueVersions>false</useUniqueVersions>
            </manifest>
        </archive>
        <excludes>
            <exclude>*.yml</exclude>
            <exclude>*.properties</exclude>
        </excludes>
    </configuration>
</plugin>

到此,關(guān)于“Spring Boot項(xiàng)目部署到Linux服務(wù)器運(yùn)行報(bào)錯(cuò)怎么解決”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI