ClassNotFoundException vs. NoClassDefFoundError
ClassNotFoundException
關於ClassNotFoundException發生的原因,這篇文章ClassNotFoundException vs. NoClassDefFoundError寫得很清晰。
總的來說就是:
- 需要載入的類在classpath中找不到,一般這種情況都是使用類似
Class.forName("oracle.jdbc.driver.OracleDriver")
的方式獲取類不存在
解決問題的思路:
- 排查匯入的jar包,對於使用maven的程式來說,就是去檢查pom.xml中的配置
- 如果配置的有的話就去看一下maven實際匯入的jar包中,對應路徑下是否有這個類
NoClassDefFoundError
關於ClassNotFoundException發生的原因,這篇文章ClassNotFoundException vs. NoClassDefFoundError寫得很清晰。
總的來說就是:
- 這個類編譯時有,但是執行時沒有
解決問題的思路:
- 縮小範圍,確定是哪個類的definition找不到。確定原因後再定解決辦法
以下我演示兩個NoClassDefFoundError的情景。
NoClassDefFoundError的情景
情景1.
B專案依賴了A專案,並配置<optional>
為true。
<dependency>
<groupId>com.example</groupId>
<artifactId>a</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional>
</dependency>
C專案依賴了B專案,並呼叫B專案中的某個方法,該方法呼叫了A專案的程式碼。
此時會發生NoClassDefFoundError
報錯。
情景2.
- B專案依賴了A專案
- C專案依賴了B專案
- C專案也依賴了A專案
C專案呼叫B專案中的某個方法,該方法呼叫了A專案xxx類的程式碼。
正常來說這個過程是沒問題的,但是B專案、C專案使用的A專案版本不同。
A專案xxx類在這兩個版本的包路徑不同。
這個是我用hutool的過程中發現的一個問題,NetUtil在專案不同版本中包位置不一樣。
Note.
需要注意的一點是,如上兩個情景,雖然都是因為少了A專案的程式碼,所以一般堆疊資訊會直接報錯是找不到A專案某個類的definition。
但如果使用A專案的程式碼是在B專案的static塊中(<cinit>
方法執行失敗),那麼此時會報的是找不到B專案這個類的definition。