Maven快照版本要這樣用才真的香!

Bug的身世之謎

今天又分享一個問題解決的故事。請看下圖框起來的錯誤,明顯就是找不到這個class嘛!

圖片

下面我們按照正常人的思路去排查這個問題,既然找不到class那就先看這個依賴的jar包有沒有,如果沒有那就是鐵證如山。

但是事與願違啊,編譯後的lib目錄下真的有這個包order-api-2.0-SNAPSHOT.jar

還是不相信,於是將order-api-2.0-SNAPSHOT.jar解壓了,看看裏面到底有沒有我們需要的class,真的有,此處心情沉重。

一般人到這裏就會懵圈了,但我還年輕啊,腦袋還夠用。接下來看看classpath的配置有沒有問題,如果order-api-2.0-SNAPSHOT.jar不在classpath中,那麼自然就是找不到class啊,機智的我。

於是查看了META-INF/MANIFEST.MF文件,發現裏面依賴的是order-api-2.0-20200225.024541-15.jar, 什麼情況,還加上時間戳了。

終於真相大白了,classpath中指向的是order-api-2.0-20200225.024541-15.jar, 但lib中只有 order-api-2.0-SNAPSHOT.jar。 所以找不到class是沒有錯的。

打包配置信息

Maven deploy的時候會自動給快照版本加時間戳,從下圖可以看的出來:

圖片

下面來看下目前項目的打包配置,如下:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.3.1</version>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.xxx.web.WebApp</mainClass>
        <addClasspath>true</addClasspath>
        <classpathPrefix>lib/</classpathPrefix>
      </manifest>
    </archive>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
</plugin>

用了assembly插件,對應的配置如下:

assembly.xml

<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
    <dependencySet>
        <outputDirectory>/</outputDirectory>
        <unpack>false</unpack>
        <includes>
            <include>${artifact}</include>
        </includes>
        <outputFileNameMapping>xxx-web.jar</outputFileNameMapping>
    </dependencySet>
    <dependencySet>
        <outputDirectory>/lib</outputDirectory>
        <useProjectArtifact>false</useProjectArtifact>
        <unpack>false</unpack>
    </dependencySet>
</dependencySets>
</assembly>

打包後目錄中會有一個jar包和一個lib目錄,如下:

-xxx-web.jar
-lib
  -xxx.jar
  -yyy.jar

解決方案

現在需要解決的問題是classpath中的快照依賴和lib目錄中實際的jar包不一致的問題。

主要是兩個插件,所以纔會有不一致的情況。

maven-jar-plugin插件中可以加上false來強制打包時 MANIFEST.MF文件不記錄的Jar時間戳版本。

maven-assembly-plugin插件需要在assembly.xml中進行修改,在dependencySet中增加outputFileNameMapping={artifact.baseVersion}.${artifact.extension}

來固定名稱,這樣就可以去掉時間戳了。

下面貼一下修改之後完整的配置:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.3.1</version>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.xxx.web.WebApp</mainClass>
        <addClasspath>true</addClasspath>
        <classpathPrefix>lib/</classpathPrefix>
        <useUniqueVersions>false</useUniqueVersions>
      </manifest>
    </archive>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
</plugin>

assembly.xml

<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
    <dependencySet>
        <outputDirectory>/</outputDirectory>
        <unpack>false</unpack>
        <includes>
            <include>${artifact}</include>
        </includes>
        <outputFileNameMapping>xxx-web.jar</outputFileNameMapping>
    </dependencySet>
    <dependencySet>
        <outputFileNameMapping>
  ${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}
        </outputFileNameMapping>
        <outputDirectory>/lib</outputDirectory>
        <useProjectArtifact>false</useProjectArtifact>
        <unpack>false</unpack>
    </dependencySet>
</dependencySets>
</assembly>

雖然解決了,但感覺還是挺麻煩的。還是spring-boot-maven-plugin插件好用啊,至少沒有出現過這個時間戳的問題,新項目建議大家用spring-boot-maven-plugin插件打包。

關於作者尹吉歡,簡單的技術愛好者,《Spring Cloud微服務-全棧技術與案例解析》, 《Spring Cloud微服務 入門 實戰與進階》作者。公衆號 猿天地 發起人。

推薦

推薦下自己的開源項目,剛興趣的先Star一個吧。

項目:https://github.com/yinjihuan/kitty-cloud

基礎框架:https://github.com/yinjihuan/kitty

福利

最近一直在送硬貨,平板啊,筆記本啊之類的,今天給大家來點軟貨吧,之前也都隔三差五的在送,今天送的還是耳機三個。

掃描下方二維碼,回覆 福利 獲取抽獎碼參與抽獎。術交流歡迎加我微信:jihuan900

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章