0

使用Maven運行測試時遇到由ClassNotFoundException引發的NoClassDefFoundError。沒有找到的類肯定存在於我的本地存儲庫中。使用Maven構建時解決NoClassDefFoundError

有問題的依賴關係如下所示:默認的作用域依賴依賴於一個jar,該作用域被標記爲提供的,而類加載器找不到的文件位於jar內。它編譯好,通過該文件不能找到,而runnig應用程序。

我已經修正了錯誤,將「提供的jar」明確地添加到我的pom中作爲運行時範圍的依賴項,但我想了解發生了什麼。

1)如果我正在運行某些測試,依賴範圍=提供的含義是什麼?我明白一個servlet容器可以有一些提供的jar,比如servlet-api.jar,但是測試呢?這在我們的pom中看起來像是一個錯誤,不是嗎? 當我們應該使用「provided」作用域時,除了servlet-api.jar(和similair web-server jars)是否還有其他情況?

2)我試圖使用maven命令行參數-U,同時尋找這個問題的解決方案。就我所知,它迫使Maven檢查遠程存儲庫,並在必要時從那裏獲取最新的依賴關係。 問題是:如果我沒有指定這個命令,怎麼回事?它會始終從本地存儲庫中獲取過時的依賴關係?如果沒有,那爲什麼我需要這個命令?

3)爲了解決這樣的問題,最好在編譯代碼時知道哪些jar是真正在類路徑上的,哪些是在運行代碼時存在的。 Maven有可能嗎?

回答

2

1)總是表示不應該將依賴關係複製到構建的工件上。測試時聲明爲提供的某些依賴項不會運行,因爲這些依賴項在運行時需要。例如,您可以通過創建自己的配置文件「測試」來解決此問題。因此,在您的「測試」配置文件中,將您的依賴項聲明爲默認範圍,這將覆蓋提供的範圍。之後,您可以使用以下命令運行測試:

`mvn <goal> -PTest` 

有關信息,請參閱Introduction on profiles

2)據我所知,命令行參數-U會導致新獲取依賴關係,因爲您的存儲庫可能被破壞(例如,如果您更改或刪除了那裏的文件)。

3)mvn dependency:tree

1

1)您可以運行使用「測試容器」測試(碼頭,Tomcat)的,在這種情況下,提供範圍是有道理的(例如,我在督促使用Tomcat,但用碼頭單元測試,他們甚至沒有提供相同版本的罐子)。

2)默認情況下,Maven會將其在本地回購庫中找到的罐子,不搜索更近的一個,如果不是快照。 如果你提供自己的罐子,你應該總是增加版本,即使它有時很煩人。

3)mvn依賴:樹可以爲您提供項目的所有依賴樹。一些IDE(我使用eclipse)爲您提供了一些不錯的UI工具。