真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

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

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

成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司十年經(jīng)驗(yàn)成就非凡,專業(yè)從事做網(wǎng)站、成都網(wǎng)站制作,成都網(wǎng)頁設(shè)計(jì),成都網(wǎng)頁制作,軟文推廣,廣告投放等。十年來已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:13518219792,我們期待您的來電!

在同一個(gè)項(xiàng)目中,包含了一個(gè)類庫的兩個(gè)不同版本

這個(gè)時(shí)候,可能就會(huì)遇到奇怪的問題

  • 代碼的邏輯不符合預(yù)期

  • 出現(xiàn)NoSuchMethodError

  • ...

先說結(jié)論,出現(xiàn)這些問題,不用懷疑,一定是當(dāng)前使用的class版本和你預(yù)期的不一致。

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

在實(shí)現(xiàn)一個(gè)功能的時(shí)候,你通過maven引入了這個(gè)庫的依賴:

commons-codec

commons-codec

1.10

此時(shí),在代碼里使用了類庫內(nèi)處理Base64的一個(gè)類,有一個(gè)這樣的實(shí)現(xiàn)

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

然后沒多久,系統(tǒng)中新增其它的功能,和其他系統(tǒng)對接的時(shí)候,引入了一個(gè)依賴。當(dāng)我們高高興興的完成了任務(wù),提交代碼時(shí),某天會(huì)遇到QA提了一個(gè)問題,XX功能現(xiàn)在不可用。

什么情況,WTF?

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

什么情況?

我們在接入其他系統(tǒng)的時(shí)候,引入了一些依賴,而這其中他會(huì)依賴一個(gè)


  org.apache.commons
  com.springsource.org.apache.commons.httpclient

而他,會(huì)把上面的com.springsource.org.apache.commons.codec-1.3.0引進(jìn)來。

此時(shí),系統(tǒng)中就會(huì)有兩個(gè)關(guān)于commons-codec的包。

而舊版本的對應(yīng)Base64的類,只支持傳入一個(gè)數(shù)組,不支持String

難道Maven這么傻,不會(huì)解決一下?

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

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

看上面的提示omitted for duplicate。而上面關(guān)于codec的依賴,是因?yàn)閍rtifactId被換成了org.springsource.org.apache.commons,這樣maven的機(jī)制就不會(huì)生效,導(dǎo)致項(xiàng)目里出現(xiàn)了兩個(gè)codec的jar。而且,codec.jar雖然對于org.springsource這個(gè)指定的,雖然artifactId是這個(gè),但里面的包名還是一樣樣的org.apache.commons,所以是相同于兩個(gè)一模一樣的Jar,只是版本不同。

這個(gè)時(shí)候,到了類加載器上場的時(shí)候了。類加載器在加載類,初始化的時(shí)候,會(huì)需要加載當(dāng)前class依賴的類,此時(shí),由于依賴低版本codec的class先被加載,從而導(dǎo)致低版本的codec被加載。

等后面再需要codec的地方又需要類的時(shí)候,此時(shí)雖然WebappClassloader可以子優(yōu)先加載,對于不同的應(yīng)用進(jìn)行資源隔離,但是對于同一個(gè)應(yīng)用內(nèi)的相同package的類,是不會(huì)重復(fù)加載的。此時(shí),有相同的請求到來時(shí),從已經(jīng)加載的資源中找到了低版本的codec,就直接用了,而這個(gè)類里沒有我們要調(diào)用的方法,就出現(xiàn)了熟悉的NoSuchMethodError。

解決

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

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

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

mvn dependency:tree

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

類似這樣:


   com.xxx
   xxx
   1.0.4
   


   org.apache.commons
   com.springsource.org.apache.commons.codec



關(guān)于“Java類加載器與類沖突怎么解決”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Java類加載器與類沖突怎么解決”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


名稱欄目:Java類加載器與類沖突怎么解決
地址分享:http://weahome.cn/article/iegjdj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部