中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java類加載器與類沖突怎么解決

發布時間:2022-01-14 10:49:11 來源:億速云 閱讀:625 作者:iii 欄目:大數據

這篇文章主要介紹了Java類加載器與類沖突怎么解決的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java類加載器與類沖突怎么解決文章都會有所收獲,下面我們一起來看看吧。

在同一個項目中,包含了一個類庫的兩個不同版本

這個時候,可能就會遇到奇怪的問題

  • 代碼的邏輯不符合預期

  • 出現NoSuchMethodError

  • ...

先說結論,出現這些問題,不用懷疑,一定是當前使用的class版本和你預期的不一致。

這里我們以 apache 的 commons-codec類庫來分析問題場景。

在實現一個功能的時候,你通過maven引入了這個庫的依賴:

<dependency>

<groupId>commons-codec</groupId>

<artifactId>commons-codec</artifactId>

<version>1.10</version>

</dependency>

此時,在代碼里使用了類庫內處理Base64的一個類,有一個這樣的實現

public static byte[] decodeBase64(String base64String) {
   return (new Base64()).decode(base64String);
}

然后沒多久,系統中新增其它的功能,和其他系統對接的時候,引入了一個依賴。當我們高高興興的完成了任務,提交代碼時,某天會遇到QA提了一個問題,XX功能現在不可用。

什么情況,WTF?

然后重跑功能,果不其然。什么情況。原來我們之前使用的commons-codec-1.10版本,并沒有被使用,而是使用了com.springsource.org.apache.commons.codec-1.3.0版本。

什么情況?

我們在接入其他系統的時候,引入了一些依賴,而這其中他會依賴一個

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>com.springsource.org.apache.commons.httpclient</artifactId>
</dependency>

而他,會把上面的com.springsource.org.apache.commons.codec-1.3.0引進來。

此時,系統中就會有兩個關于commons-codec的包。

而舊版本的對應Base64的類,只支持傳入一個數組,不支持String

難道Maven這么傻,不會解決一下?

他會根據引入的版本,使用的maven的版本,從而選擇是根據依賴聲明的前后順序或者是nearest來使用。但這個解決不了我們上面的問題,因為maven對于同一個groupId和artifactId才會使用上面這個依賴機制,所以相同的groupId和artifactId的依賴,會直接忽略,最終只使用一個。依賴樹上可以看了出來:

Java類加載器與類沖突怎么解決

看上面的提示omitted for duplicate。而上面關于codec的依賴,是因為artifactId被換成了org.springsource.org.apache.commons,這樣maven的機制就不會生效,導致項目里出現了兩個codec的jar。而且,codec.jar雖然對于org.springsource這個指定的,雖然artifactId是這個,但里面的包名還是一樣樣的org.apache.commons,所以是相同于兩個一模一樣的Jar,只是版本不同。

這個時候,到了類加載器上場的時候了。類加載器在加載類,初始化的時候,會需要加載當前class依賴的類,此時,由于依賴低版本codec的class先被加載,從而導致低版本的codec被加載。

等后面再需要codec的地方又需要類的時候,此時雖然WebappClassloader可以子優先加載,對于不同的應用進行資源隔離,但是對于同一個應用內的相同package的類,是不會重復加載的。此時,有相同的請求到來時,從已經加載的資源中找到了低版本的codec,就直接用了,而這個類里沒有我們要調用的方法,就出現了熟悉的NoSuchMethodError。

解決

問題了解清楚了,那該怎么解決呢,引入一個依賴的時候,總不能一個個的去查看jar的pom聲明。

出現了上述問題時,如果不是使用maven管理依賴的,像之前SSH那種一下添加一堆jar到lib目錄的時候,確定了對應的問題jar后,直接刪除就好,簡單直接。

如果是用maven管理依賴,就需要了解,是請把這小子帶到這兒的。這個時候,使用maven的命令工具:

mvn dependency:tree

然后把結果生成到一個文件中,就可以查看引入沖突的jar是誰引進來的,查明真相后,就把依賴排除出去,

類似這樣:

<dependency>
   <groupId>com.xxx</groupId>
   <artifactId>xxx</artifactId>
   <version>1.0.4</version>
   <exclusions>

<exclusion>
   <groupId>org.apache.commons</groupId>
   <artifactId>com.springsource.org.apache.commons.codec</artifactId>
</exclusion>


</exclusions>
</dependency>

關于“Java類加載器與類沖突怎么解決”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Java類加載器與類沖突怎么解決”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沿河| 崇左市| 邓州市| 阿勒泰市| 金寨县| 郸城县| 依兰县| 黎城县| 河北省| 佛学| 垫江县| 天长市| 晋宁县| 新野县| 疏附县| 如东县| 延安市| 南京市| 临武县| 错那县| 邮箱| 桐庐县| 颍上县| 沁阳市| 横峰县| 滁州市| 嵊泗县| 扬中市| 新晃| 洛南县| 类乌齐县| 宣威市| 咸丰县| 七台河市| 昌黎县| 涞水县| 德江县| 乳山市| 务川| 禹城市| 札达县|