<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-72  評論-20  文章-0  trackbacks-1
    1         問題背景
    我們都知道,Java平臺一大亮點(diǎn)就在于其類裝載器體系結(jié)構(gòu),這使得JVM可以在運(yùn)行期從Java API,擴(kuò)展路經(jīng)(java.ext.path),classpath以及用戶指定的位置(文件或網(wǎng)絡(luò))中載入所需的class,從而達(dá)到動態(tài)裝載的目的。然而其類裝載器委托模型在保證了安全性和強(qiáng)大功能的同時,也導(dǎo)致了相當(dāng)?shù)膹?fù)雜性,有很多地方一旦我們不加注意的話就將導(dǎo)致錯誤。這里我希望通過一些小例子來展示動態(tài)裝載的某些方面,深入地了解一下怎么進(jìn)行動態(tài)裝載,會遇到什么樣的問題,并就問題的原因與解決方法進(jìn)行討論。
    也許有人會說:我的程序不用什么動態(tài)裝載,平時運(yùn)行程序就是java –classpath … myPkg.my不就行了嗎?不過我總是聽前輩說,要想完全了解一個系統(tǒng)下的程序設(shè)計(jì),就必須要深入研究這個平臺的特性,做到心中有數(shù),做起程序才不會處處制肘。類的動態(tài)裝載是Java平臺最顯著的特征之一,許多著名的項(xiàng)目—Tomcat,Eclipse都使用自定義類裝載器來裝載運(yùn)行時所需的類,如果連什么是動態(tài)裝載和怎么動態(tài)裝載都沒弄明白,還能去玩自定義類裝載器嗎?所以還是不要浮躁,讓我們從基礎(chǔ)開始做起吧。
    不過,我要說明的是你在看我這篇文章之前最好先熟悉一下Java的類裝載器體系結(jié)構(gòu)以及其委托模型,我在這里將不加贅述,推薦先看《Java深度歷險》或《深入Java虛擬機(jī)》的第八章。
    2         問題研究
    我要討論的問題是:讓一個在my/目錄下名為my.Main的類在運(yùn)行期讀取util/中的util.Tool類。
    l      實(shí)驗(yàn)一
    我的實(shí)驗(yàn)?zāi)夸浗Y(jié)構(gòu)如下
    其中my.Main的代碼如下:
    util.Tool的代碼如下:
    在my.Main的代碼中16行可以看到,我定義了一個URLClassLoader,想要讀取在同一根目錄下的/util/Tool.class,接下來我們運(yùn)行如下命令,來查看運(yùn)行結(jié)果:
    如上可見,util.Tool被順利裝載了,可是裝載它的卻是AppClassLoader,而不是我們想要的URLClassLoader!這是為什么呢?
    原因很簡單,因?yàn)槲覀儗til/Tool.class放到了JVM系統(tǒng)變量”user.dir”所指定的目錄下,而該JVM系統(tǒng)變量的默認(rèn)值為程序所在的根目錄,相當(dāng)于把classpath 設(shè)置成了”.”,也就是相當(dāng)于執(zhí)行了命令:
    java –classpath . my.Main
    于是,正因?yàn)閡til.Tool在classpath下,于是JVM就在在載入my.Main的同時也用AppClassLoader將util.Tool載入到JVM了。我們可以通過如下命令看得更清楚一些:
    java –verbose my.Main
    看到了嗎?由于AppClassLoader預(yù)先載入了util.Tool類,而且在URLClassLoader的loadClass()方法中有如下語句:Class cls = getLoadedClass(String className);如果cls!=null的話,loadClass()就會返回已經(jīng)載入過的(即由AppClassLoader所載入的)util.Tool類,所以我們才會看到以上結(jié)果。
    l      實(shí)驗(yàn)二
    為了解決以上問題,我決定按如下方式組織我的目錄結(jié)構(gòu)
    然后對Main.class進(jìn)行一些修改:
    嗯,這下我們不會為util.Tool被提前載入而煩惱了,因?yàn)檩d入my.Main的AppClassLoader找不到換了位置的util.Tool類了。這回可能有人會問:subdir不是還在”user.dir”所指向的目錄下嗎?怎么只是多建了一層目錄它就找不到了呢?原因是AppClassLoader是URLClassLoader的子類,它在載入class的時候也是根據(jù)該類的URL來進(jìn)行定位的。那我們的例子來說,在“實(shí)驗(yàn)一”的最后一個圖中我們可以看到,util.Tool被載入的位置為:file1:c:/Test1,JVM得到這個URL之后,將util.Tool中的”.”變?yōu)?#8221;/”,在所得字符串結(jié)尾處加上”.class”,最后將該字符串加到file1:c:/Test1后面,就得到了最終util.Tool的URL:file1:c:/Test1/util/Tool.class。而當(dāng)加了一層subdir目錄之后,AppClassLoader就找不到file1:c:/Test1/util/Tool.class了,而只能由程序中定義的URLClassLoader來載入。
     這時我們運(yùn)行程序,所得結(jié)果如下:
    可以看到,util.Tool確實(shí)已經(jīng)我定義的URLClassLoader被載入并初始化了,可是為什么最后卻有一個奇怪的異常呢?NoClassDefFoundError?util.Tool類不是都載入了嗎?怎么還找不到它的定義呢?
    這個問題需要從JVM的裝載機(jī)制說起。對于每個JVM實(shí)例,除了內(nèi)置的三個內(nèi)置的類裝載器(BootStrapClassLoader,ExtClassLoader,AppClassLoader)之外,還可能有一些用戶自定義的類裝載器,而這些類裝載器可能在一個程序運(yùn)行周期內(nèi)載入同一個類,即AppClassLoader和我自定義的類裝載器MyClassLoader可能同時需要載入util.Tool類。為了避免沖突,JVM為每個類裝載器都建立一個命名空間,并以此作為其訪問邊界。例如,如果my.Main想要引用util.Tool類,則它們必須是由同一裝載器載入的,也就是說,由于my.Main是由AppClassLoader載入的,那么util.Tool也必須由AppClassLoader載入才行,否則就會出現(xiàn)上述錯誤。
    問題解決的方法很簡單,只需要讓my.Main和util.Tool由同一類裝載器載入就行了。
    l      實(shí)驗(yàn)三
    為了讓my.Main和util.Tool由同一類裝載器載入,我定義了一個啟動類—boot.BootStrap類:
    在這里,我用自己的類裝載器ucl來裝載my.Main類,并用reflection API來調(diào)用其main()方法,同時也對my.Main稍作修改
    然后執(zhí)行一下看看結(jié)果:
    圖中可以很清楚的看到BootStrap類則是由AppClassLoader載入的,而Main類和Tool類都是由同一個URLClassLoader在運(yùn)行期動態(tài)載入的。至此,我們完成了對類的動態(tài)載入的全部說明和實(shí)驗(yàn),希望對你能有所幫助。 
    posted on 2007-07-27 22:28 前方的路 閱讀(368) 評論(1)  編輯  收藏 所屬分類: Java技術(shù)

    評論:
    # re: 動態(tài)裝載問題的研究 2012-03-29 11:21 | yangzg
    似懂非懂  回復(fù)  更多評論
      
    主站蜘蛛池模板: 一本色道久久88亚洲精品综合 | 美女一级毛片免费观看| 免费国产成人高清视频网站| 女人隐私秘视频黄www免费| 亚洲一区二区影院| 午夜视频在线观看免费完整版| 久久久久久亚洲av无码蜜芽| 区久久AAA片69亚洲| 国产成人免费午夜在线观看| 国产成人亚洲综合无| 亚洲综合在线视频| 日韩免费一级毛片| 日本免费中文视频| 色欲aⅴ亚洲情无码AV蜜桃| 国产精品国产亚洲精品看不卡| 两个人的视频高清在线观看免费| 国产日韩久久免费影院| 亚洲人成电影网站| 亚洲人成人无码网www电影首页 | 免费日本黄色网址| 中文字幕免费观看| 一级毛片成人免费看a| 亚洲乱人伦精品图片| 亚洲无线观看国产精品| 国产精品黄页在线播放免费| 中文字幕天天躁日日躁狠狠躁免费| 四虎国产精品永免费| 久久精品国产亚洲av麻豆蜜芽| 亚洲精品午夜国产VA久久成人| 国产黄色片在线免费观看| 97国产免费全部免费观看 | 成人亚洲网站www在线观看| 久草视频在线免费| 国产啪精品视频网站免费尤物| 免费亚洲视频在线观看| 亚洲人成人网毛片在线播放| 亚洲欧洲国产精品你懂的| 伊人久久精品亚洲午夜| 日本xxwwxxww在线视频免费| 国产福利在线免费| 免费看搞黄视频网站|