明明有class為什么還是報ClassNotFoundException?


描述

我們修改接口時,習慣發布一個快照版本用於測試。我們的一個服務也是發布了快照版本,然后一個jar程序要依賴這個服務,修改pom文件打包部署后,通過 java -jar 命令執行這個jar程序,然后你懂的啟動后報錯了
Exception in thread "main" java.lang.NoClassDefFoundError
...
Caused by: java.lang.ClassNotFoundException: ...

file

分析

lib包下有這個接口從屬的jar包

file

讀到這里先不要往下看,想下為何會報找不到類呢?

在打包時會同時生成一個MANIFEST.MF文件,描述了jar包的基本信息

Main-Class 指定程序的入口,可以用java -jar *.jar 來啟動

Class-Path 指定jar包依賴關系,類加載器會根據該路徑來加載class

好的,我們了解了MANIFEST.MF文件,那么我們看下這個文件,可能有的讀者還不清楚怎么找這個文件,解壓你程序的jar就行,unzip *.jar 就可以看到了

file

看到Class-Path中報錯的類在我用紅框圈起的jar包中,可以發現這個jar包的名字和我們的lib包中對應的jar名字並不一樣

lib包中是dspadinfo.client-0.0.41-SNAPSHOT.jar

而在MANIFEST.MF文件中是dspadinfo.client-0.0.41-20190902.070402-1.jar,是一個帶有時間戳的形式,說明給Snapshot Version 這種快照版本的jar打包時用了唯一版本,這個是默認的,名字對不上,所以加載不到對應的類,報了上面的錯

解決

maven官方文檔中有對處理快照版本的介紹,連接http://maven.apache.org/shared/maven-archiver/examples/classpath.html

要想強制使用 '-SNAPSHOT'的版本命名,只需要把 給禁用就行

<useUniqueVersions>false</useUniqueVersions>

給大家我的項目中的配置,作為參考

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              <mainClass>*.dsp.redispositive.Application</mainClass>
              <useUniqueVersions>false</useUniqueVersions>
            </manifest>
          </archive>
        </configuration>
</plugin>

修改完pom文件后,重新打包部署后,MANIFEST.MF文件中的Class-Path中的jar包就是 dspadinfo.client-0.0.41-SNAPSHOT.jar 執行沒有問題

file

希望你遇到類似的問題,可以想到這個解決辦法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM