往事如風(fēng)
          記錄工作中的點點滴滴 留住那些淡淡的回憶
          posts - 6,  comments - 3,  trackbacks - 0

          最近在做一個項目,綜合使用了jboss的microcontainer,jetty和自己定義的war包,war包中還會用到spring,因為牽涉到多個容器,同時又有自己的自定義類,所以classloader環(huán)境異常復(fù)雜,ClassNotFound問題搞得頭都大了,最后綜合各種因素,設(shè)計了如下的一個classloader層次:

          cl.png

          其中,紅色部分是系統(tǒng)(也就是啟動java程序加載Main函數(shù)的classloader),主要的設(shè)計考量有以下幾點:

          1、使用自定義的ExtClassLoader(加載java的ext目錄下的jar包)把程序加載的class完全和系統(tǒng)加載的class隔離開,這樣即使在eclipse容器中啟動都不會有類沖突。

          為什么不從系統(tǒng)的ExtClassLoader作為自定義classloader數(shù)的根有兩個考慮,第一個是系統(tǒng)ExtClassLoader有可能不存在,第二個就是如果使用同一個ExtClassLoader中,在處理JNDI、XML和URL解析等java擴展功能時會遇到后加載的handler部分導(dǎo)致不同classloader樹加載的同一個類的ClassCastException,具體參見這些模塊的源代碼。

          2、WarClassLoader除了系統(tǒng)類和Common類(目前只有l(wèi)og相關(guān)類)以外的類都從war包的WEB-INFO和classes下加載。

          3、所有執(zhí)行War包中代碼的線程ThreadContextClassLoader都設(shè)置為WarClassLoader,以供Spring和Webx中的相關(guān)工具類使用這個classloader結(jié)構(gòu)的后門來加載war包中的類,典型例子是Webx中ResourceLoaderService就是使用ContextClassLoader來加載類的。

          4、RialtoClassLoader也就是這個項目的容器加載器和WarClassLoader不在同一個樹路徑上,可以避免程序使用類和war使用類的class沖突,典型的是Spring容器相關(guān)代碼。

          5、CommonClassLoader加載的類需要嚴(yán)格控制,否則可能會導(dǎo)致運行期類沖突,例如Spring的相關(guān)jar包絕對不可以出現(xiàn)在這個classloader作用范圍內(nèi)。

          總之,ClassLoader采用父分派機制,后來增加的Thread ContextClassLoader在這個體系上增加了一個后門,帶來了靈活性,也帶來了很多令人困擾的問題,在做容器類的項目時難免會遇到class loader層次設(shè)計的問題,這里拋磚引玉,歡迎達人拍磚。

          posted on 2010-07-14 19:18 井底青蛙,常望天空 閱讀(1070) 評論(0)  編輯  收藏 所屬分類: java

          <2010年7月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 嵩明县| 大洼县| 兴隆县| 姚安县| 简阳市| 涪陵区| 宁河县| 元谋县| 东港市| 赫章县| 湘乡市| 佛坪县| 社会| 双辽市| 信丰县| 惠安县| 济源市| 南靖县| 巴林左旗| 双辽市| 博客| 西畴县| 东源县| 德格县| 吴江市| 西乌珠穆沁旗| 丰镇市| 鄂托克旗| 若羌县| 永福县| 平谷区| 英德市| 肃宁县| 郯城县| 通道| 阳泉市| 日照市| 凌云县| 那曲县| 哈巴河县| 高淳县|