<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          類加載常見錯誤總結(jié),寫得非常好!

          共 2836字,需瀏覽 6分鐘

           ·

          2021-05-05 00:32

          點擊上方藍色“肉眼品世界”,選擇“設(shè)為星標

          深度價值體系傳遞!


          作者:fredalxin
          地址:https://fredal.xin/classloader-error


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

          類加載

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

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

          此外我們比較需要知道的幾點:

          ClassNotFoundException

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

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

          ClassNotFoundException 是一個 exception 類,同時發(fā)生在主動執(zhí)行動態(tài)加載時,所以我們應(yīng)該去 catch 它,防止發(fā)生一些運行時錯誤。

          NoClassDefFoundError

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

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

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

          NoSuchMethodError

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

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

          這種情況我們首先得知道 jvm 到底加載的是什么版本,這可以使用-verbose:class來確定。

          LinkageError

          LinkageError 相比較之前幾種錯誤不那么常見,只有多個類加載器同時作用交互時才會出現(xiàn)。

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

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

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

          還有一種比較常見的情況是進行自定義類加載器開發(fā)時遇到。比如開發(fā)類隔離容器時,期望將某些中間件都由與應(yīng)用不同的獨立類加載器加載,但這時候如果中間件依賴 spring context,而應(yīng)用本身也依賴 spring context,那么 作為 spring bean 交互時候就會妥妥報 LinkageError 了。

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

          Some Tips

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

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

          推薦閱讀:

          世界的真實格局分析,地球人類社會底層運行原理

          企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

          論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

          企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

          【中臺實踐】華為大數(shù)據(jù)中臺架構(gòu)分享.pdf

          數(shù)字化轉(zhuǎn)型的本質(zhì)(10個關(guān)鍵詞)

          小米用戶畫像實戰(zhàn),48頁PPT下載

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 51
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲特级毛片精品久久 | 人人看人人摸人人透 | 国产精品久久视频 | 欧美老妇操逼 | 热99视频 |