posts - 80,comments - 749,trackbacks - 2

          Flier Lu問(wèn)到CLR LoaderJava Class Loader有什么不一樣。要回答這個(gè)問(wèn)題不容易,因?yàn)槲覍?duì)Java一竅不通。但既然問(wèn)題提出來(lái)了,打腫臉來(lái)充胖子也得回答啊。

           

          于是今天下午我在google上逛了一圈,找了些關(guān)于Java Class Loader的文章看了看。我的結(jié)論是,和Java Class Loader類似的東東,在CLR里是不存在的。

           

          簡(jiǎn)單的說(shuō),CLR里不存在一個(gè)類似于Java.Lang.ClassLoader的東西。所以你無(wú)法實(shí)現(xiàn)你自己的CLR LoaderCLR里只有一個(gè)Loader,那就是CLR Loader。當(dāng)然,CLR提供了自己獨(dú)特的方式讓你做動(dòng)態(tài)裝載。你所擁有的自由度是遠(yuǎn)比Java要大得多。

           

          下面是具體分析。

           

          我對(duì)Java Class Loader的理解主要是從這兩篇文章里來(lái)的。

          “Inside Class Loader” by Andeas Schaefer (http://www.onjava.com/lpt/a/4337) “The basics of Java Class Loaders” by Chuck McManis (http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth_p.html)。我看了看JVM Spec。但是我覺(jué)得不如上面兩篇文章清楚。

           

          先說(shuō)Java里的Type吧。Java里的Type就是Class Class就是Namespace + class name.  Class通過(guò)Class Loader來(lái)裝載的。System Class Loader缺省的話只在CLASSPATH中尋找Class。如果你要在CLASSPATH之外轉(zhuǎn)載Class的話,你就需要自己的Class Loader。如果兩個(gè)Class有相同的名字,并且在同一個(gè)Class Loader里,那么它們就被JVM認(rèn)為是相同的,可以互相賦值。如果有一個(gè)不一樣的話,它們就被認(rèn)為是不一樣的。互相賦值會(huì)發(fā)生ClassCaseException。換句話說(shuō),Class name + Class Loader是一個(gè)Type的獨(dú)特的ID

           

          Java的這個(gè)模型有很多問(wèn)題。首先它把Class name做為TypeID。兩個(gè)Class如果有同樣的名字,但是實(shí)際內(nèi)容不一樣的話,如果它們被同一個(gè)Class Loader裝載,JVM會(huì)認(rèn)為它們是同一個(gè) Type。這個(gè)太搞笑了。結(jié)果就是Class Loader必須要有一些特別的辦法來(lái)管理Class name。一般的辦法是加一個(gè)前綴,比如說(shuō)ClassURL。如果Namespace管理不好的話,很容易就是安全漏洞。這是為什么JVM Spec里提到Class Loader必須要讓Parent Class Loader先搜索Class,再自己尋找。而且Class loader必須要保存Class resolution的結(jié)果,這樣下次Class resolution的時(shí)候,Class loader會(huì)返回同樣的結(jié)果。Java Class Loader有太多的限制,同時(shí)又有太多的責(zé)任。

           

          另一個(gè)問(wèn)題是共享問(wèn)題。如果同一個(gè)Class被兩個(gè)不同的Class Loader裝載的話,JVM認(rèn)為這兩個(gè)Class不是同一個(gè)Type,不能互相賦值。結(jié)果就是Class無(wú)法共享。被不同Class Loader裝載的Class無(wú)法直接對(duì)話。直接對(duì)話會(huì)產(chǎn)生linkage錯(cuò)誤。它們只能間接對(duì)話,比如通過(guò)Interface,或者共同的Base Class

           

          還有一個(gè)問(wèn)題是Versioning。因?yàn)?/span>JavaType里只有名字,所以當(dāng)你看到一個(gè)Type的時(shí)候,你無(wú)法知道它是第一版,還是第二版。所以如果你需要第二版,但是Class loader給你裝載了第一版的時(shí)候,祈禱吧。也許上帝能救你。

           

          現(xiàn)在回過(guò)頭來(lái)看看CLR的模型。CLRType包括兩部分:Class name + Assembly NameClass name是和 JavaType類似的東西,就是namespaceAssemblyJava沒(méi)有的東西。Assembly Name的屬性包括Name, Version, Culture, PublicKey(Token) 如果兩個(gè)Assembly有一個(gè)屬性不一樣,那么它們就認(rèn)為是不一樣的。兩個(gè)Type如果有同樣的Class name,但是Assembly Name不一樣的話,它們也認(rèn)為是不一樣的。

           

          CLRType引用總是包括Class name Assembly Name的。所以CLR在尋找一個(gè)Type的時(shí)候,主要是尋找Assembly。找到了Assembly之后,CLR看看這個(gè)Assembly里有沒(méi)有這個(gè)Class。有的話就萬(wàn)事大吉,沒(méi)有的話就是TypeLoadException

           

          CLR區(qū)別Type主要靠AssemblyAssemblyPublicKey(Token)。別人無(wú)法冒充你。所以象Java里的namespace的問(wèn)題就不存在了。Assembly有自己的Version。你要第二版的時(shí)候CLR不會(huì)裝載第一版給你。所以象Java Class Loader那樣的限制,責(zé)任和問(wèn)題都不存在了。從這個(gè)角度上講,這正是為什么CLR里沒(méi)有象Java Class Loader那樣的東西。

           

          但并不是說(shuō)你就不能動(dòng)態(tài)裝載了,而是說(shuō)你動(dòng)態(tài)裝載的時(shí)候就不用考慮那些垃圾了。

           

          關(guān)于共享的問(wèn)題,因?yàn)闆](méi)有了你自己的Class loader,所以任何Type都可以直接對(duì)話。同樣的Type也不會(huì)因?yàn)?/span>Class Loader不一樣而被認(rèn)為不一樣。

           

          CLR Loader有自己的規(guī)則怎么尋找Assembly。它先看GAC,再看你的程序目錄。都沒(méi)有的話它還有一個(gè)AssemblyResolveEvent去問(wèn)你,看你能不能提供。如果你要?jiǎng)討B(tài)裝載的話,你有Assembly.Load, Assembly.LoadFrom, Assembly.LoadFile, Assembly.Load(byte[])。你可以提供privateBin,你也可以提供codebase hint。你還能有policy。總之,你想從哪找,就可以去哪找。細(xì)節(jié)問(wèn)題我就不多說(shuō)了。你可以去看MSDNSuzanneBlogAlanBlog,和我的英文Blog.

           

          結(jié)論,CLR Loader遠(yuǎn)比Java Class Loader要Secure, Powerful and Flexible

          posted on 2005-03-28 11:34 Brian Sun 閱讀(706) 評(píng)論(1)  編輯  收藏 所屬分類: 軟件轉(zhuǎn)貼

          FeedBack:
          # re: CLR Loader and Java Class Loader Compared[轉(zhuǎn)][未登錄](méi)
          2009-06-06 19:06 | test
          簡(jiǎn)直是一派胡言,不懂就不要寫文章  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 鄢陵县| 昌乐县| 西城区| 乌鲁木齐市| 桐柏县| 宁津县| 汨罗市| 开江县| 静海县| 泸溪县| 桐柏县| 邵东县| 雅安市| 威信县| 贵定县| 阿克陶县| 新巴尔虎右旗| 定陶县| 上犹县| 东乌珠穆沁旗| 句容市| 阳原县| 喀喇| 石棉县| 嘉善县| 米脂县| 安徽省| 星座| 浮梁县| 靖州| 石台县| 白水县| 榆社县| 龙门县| 尖扎县| 唐山市| 额尔古纳市| 荔波县| 昆明市| 南溪县| 定日县|