日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
類加載常見錯(cuò)誤總結(jié),寫得非常好!

最近在做類隔離相關(guān)的一些工作,而恰恰之前協(xié)助開發(fā)同學(xué)時(shí)也發(fā)現(xiàn)會(huì)遇到許多類加載相關(guān)的異常,并且往往比較難定位與解決。這里簡(jiǎn)單做一個(gè)小總結(jié)。

十余年的越城網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營(yíng)銷網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整越城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“越城網(wǎng)站設(shè)計(jì)”,“越城網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

類加載

首先我們來(lái)捋一捋類加載的基礎(chǔ)知識(shí)。

以上是大家比較熟悉的類加載器模型,主要包含 3 種類加載器:

  •  BootstrapClassloader 根加載器,也就是系統(tǒng)類加載器,加載核心庫(kù),如 rt.jar。
  •  ExtensionClassloader 擴(kuò)展類加載器,主要加載/ext/下面的 jar 包
  •  AppClassloader 離我們最近的類加載器,負(fù)責(zé)加載 classpath 下的類,開發(fā)時(shí)候我們的代碼大部分由其加載。

此外我們比較需要知道的幾點(diǎn):

  •  一個(gè)類是由 jvm 加載是通過(guò)類加載器+全限定類名確定唯一性的。
  •  雙親委派,眾所周知,子加載器會(huì)盡量委托給父加載器進(jìn)行加載,父加載器找不到再自己加載
  •  線程上下文類加載,為了滿足 spi 等需求突破雙親委派機(jī)制,當(dāng)高層類加載器想加載底層類時(shí)通過(guò) Thread.contextClassLoader 來(lái)獲取當(dāng)前線程的類加載器(往往是底層類加載器)去加載類。

ClassNotFoundException

ClassNotFoundException 表示類找不到異常,是一種 Exception,通常發(fā)生在載入階段,當(dāng)開發(fā)者主動(dòng)調(diào)用 Class.forName()、ClassLoader.loadClass()或 ClassLoader.findSystemClass()動(dòng)態(tài)加載指定類時(shí)候,類加載器就會(huì)去 classpath 下尋找類,如果找不到就會(huì)拋出此錯(cuò)誤。

還有另外一種情況是當(dāng)一個(gè)類已經(jīng)被某個(gè)類加載器加載到內(nèi)存中,另外一個(gè)類加載器試圖去加載時(shí)也會(huì)發(fā)生錯(cuò)誤。

ClassNotFoundException 是一個(gè) exception 類,同時(shí)發(fā)生在主動(dòng)執(zhí)行動(dòng)態(tài)加載時(shí),所以我們應(yīng)該去 catch 它,防止發(fā)生一些運(yùn)行時(shí)錯(cuò)誤。另外,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):JVM46,可以獲取一份 46 頁(yè)的 JVM 高清教程,非常齊全。

NoClassDefFoundError

NoClassDefFoundError 是一種和 ClassNotFoundException 很像的錯(cuò)誤,只不過(guò)它是更嚴(yán)重的 error 類型。它發(fā)生在鏈接階段,表示 jvm 在編譯階段可以找到相應(yīng)的類,但在執(zhí)行過(guò)程中卻找不到相應(yīng)的類。

一種原因是由于在編譯后運(yùn)行前類被更改或者刪除了。另外一種則是 classpath 本身被修改過(guò)了,這可以通過(guò)System.getProperty("java.classpath")來(lái)找到程序?qū)嶋H運(yùn)行的 classpath,或者通過(guò)-classpath 命令來(lái)指定正確的 classpath。

那如果是在 ide 中開發(fā),很多時(shí)候出現(xiàn)的情況是我們可以通過(guò) ide 編譯通過(guò),但在實(shí)際運(yùn)行的 WEB-INF/lib 下卻是沒有的。所以排查的時(shí)候我們需要去實(shí)際的 war 包下面確定是否有類。

NoSuchMethodError

我們還會(huì)遇到 NoSuchMethodError 錯(cuò)誤,它表示找不到方法,但找不到方法歸根結(jié)底是找到了不正確的類。

通常情況下是因?yàn)?jar 包沖突問(wèn)題,即加載了不匹配版本的類導(dǎo)致的。例如應(yīng)用中有 A、B 兩個(gè)二方包,A 依賴 C-v1 包,而 B 依賴 C-v2 包,如果 maven 仲裁最后使用的是 C-v1 包,那么當(dāng) B 加載到 C-v2 中有而 C-v1 中沒有的方法時(shí)就會(huì)報(bào) NoSuchMethodError。

這種情況我們首先得知道 jvm 到底加載的是什么版本,這可以使用-verbose:class來(lái)確定。Java 系列教程及實(shí)踐源碼:https://github.com/javastacks/javastack

LinkageError

LinkageError 相比較之前幾種錯(cuò)誤不那么常見,只有多個(gè)類加載器同時(shí)作用交互時(shí)才會(huì)出現(xiàn)。另外,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):面試,可以獲取我整理的 JVM 系列面試題和答案,非常齊全。

我們知道 jvm 中一個(gè)類由全限定類名與類加載器確定類實(shí)例,那么不同類加載器加載的同一個(gè)類是屬于不同類實(shí)例的,然后在內(nèi)存中如果兩者發(fā)生交互,就會(huì)出現(xiàn) LinkageError 異常。

一般情況下,jvm 加載類都會(huì)遵循之前所述的雙親委派原則,不太可能出現(xiàn)一個(gè)類有不同類加載器加載的情況。但在諸如 tomcat 之類的 javaEE 環(huán)境中,常常出這種狀況,這是由于 tomcat 上的 web 應(yīng)用類加載機(jī)制稍有不同,每個(gè)資源模塊(比如一個(gè) war 包)都優(yōu)先使用自身的資源,突破了雙親委派模型:

當(dāng) appClassLoader 加載類時(shí)候,會(huì)首先在自己的本地資源庫(kù)中查找類,其次才會(huì)走雙親委派模型。那么如果一個(gè)類 A 由 AppClassLoaderx 加載,但其超類在 AppClassLoader 中沒有,只有委托 CommonClassLoader 才能找到,當(dāng)類 A 與其超類進(jìn)行交互時(shí)就會(huì)報(bào)錯(cuò)了。

還有一種比較常見的情況是進(jìn)行自定義類加載器開發(fā)時(shí)遇到。比如開發(fā)類隔離容器時(shí),期望將某些中間件都由與應(yīng)用不同的獨(dú)立類加載器加載,但這時(shí)候如果中間件依賴 spring context,而應(yīng)用本身也依賴 spring context,那么 作為 spring bean 交互時(shí)候就會(huì)妥妥報(bào) LinkageError 了。Spring Boot 系列教程推薦:https://github.com/javastacks/spring-boot-best-practice

解決這個(gè)問(wèn)題的辦法包括 2 種,即控制不同類加載器加載的類不進(jìn)行交互,或者都交于一個(gè)共同的父加載器進(jìn)行加載。

Some Tips

總結(jié)一下以上幾種錯(cuò)誤。ClassNotFoundException 以及 NoClassDefFoundError 都是由于加載不到類導(dǎo)致的,而 NoSuchMethodError 是因?yàn)榧虞d了不正確的類,LinkageError 則是由于同一個(gè)類被多個(gè)類加載器加載所導(dǎo)致的。

以上這些問(wèn)題都可以使用arthas進(jìn)行排查。例如使用 sc 命令來(lái)查看 JVM 已加載的類信息,包括從哪個(gè) jar 包讀取,由哪個(gè)類加載器加載。使用 jad 命令來(lái)查看 jvm 中反編譯的代碼,可以定位到底到底有沒有所需 method。以及使用 classloader 命令,來(lái)查看當(dāng)前所有 classloader 的信息,包括加載的 urls,是否能加載到指定的類或者 resources 等。


網(wǎng)站題目:類加載常見錯(cuò)誤總結(jié),寫得非常好!
地址分享:http://m.5511xx.com/article/cdoodsh.html