Maven 依賴 install 原

基礎

首先明確:

  1. mvn install 出來的 jar 包只會包含自己的 src 的 classes. 即使你是 compile 的依賴, 也不會進去, 但是如果打成 war 包, 是會包含 compile scope 的依賴的. 而 provided 是要容器提供, 比如說 Tomcat, 會到 Tomcat 的 $liferay-tomcat-home\webapps\ROOT\WEB-INF\lib 目錄下找. 而且 compile 的依賴是傳遞的, provided 的不傳遞.
  2. 可以通過 assembly/shade 插件把依賴的 jar 包打到一個 assembly.jar 包中去. 和源碼的 jar 包可以是獨立的, 也可以打到一起. 如果你一個依賴(D1)有兩個版本(在父/子pom 中都有定義, 但是版本不一樣), 在打出的 jar 包裏只會有一個版本, 因爲路徑裏不帶版本的. 所以會出現各種 NoSuchMethodError 等等問題, 因爲編譯的時候都是各自用的正確的 D1 編譯的出的 class. 但是運行時用到的 D1 只會有一個版本, 會有不匹配.

所以, 不要在一個項目裏, 不同 pom 裏面嘗試使用不同 version 的依賴. 來看個實例:

parquet-column 裏會 shade 一個 fasttuil, 你 jar -tf parquet-column.jar 看他 裏面會有這個 fastutil.

可以看到有兩個 jar 包, 一個 origin 不帶 shade 的 fastutil, 另外一個是帶着的, 也是放到 maven 倉庫的 jar 包.

jar -tf 確認

問題定位

  1. 如果有遇到什麼 NoSuchMethodError, ClassNotFoundException 等等的, 先看看打印出來的 classpath. IDEA 裏可以直接看:

  2. 然後可以 double shift, 搜下出問題的類, 一般會跳出來多個:

  3. 然後再用 mvn dependency:tree 看下當前 model 用的哪個版本的依賴

然後就可以做相應的操作, 一般有以下幾種:

1. exclusive 相應依賴
2. 寫死用一個版本的
3. 把 dependency 的依賴做 external 模塊, 然後 shade + reloaction, 可以參見 spark 的 external model.

番外

我們經常回用到 -pl :moduleName, 看着很奇怪, 其實:前面省略的是 groupId.

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