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

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

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

    cuiyi's blog(崔毅 crazycy)

    記錄點滴 鑒往事之得失 以資于發展
    數據加載中……

    ClassLoader專題(五):ear的闡述(引用) 和 驗證后的推理

    robbin在其文 http://www.javaeye.com/topic/11 中如下描述

    Java本身是一種設計的非常簡單,非常精巧的語言,所以Java背后的原理也很簡單,歸結起來就是兩點:

    1、JVM的內存管理

         理解了這一點,所有和對象相關的問題統統都能解決

    2、JVM Class Loader

         理解了這一點,所有和Java相關的配置問題,包括各種App Server的配置,應用的發布問題統統都能解決
    App Class Loader
    |----- EJB Class Loader
    |----- Web App Class Loader

    如果在App Class Loader級別配置,是全局可見的。
    如果打包在EJB里面,那么就不會影響到Web Application,反之亦然,如果你在WEB-INF下面放置Hibernate,也不會影響到EJB。
    放在EJB Class Loader或者放在Web App Class Loader級別主要就是在局部范圍內有效,不影響到其它的應用。
    #me:這里是說ClassLoader都有一個加載邊界#

    試想,如果在一個Weblogic上面配置多個虛擬域,你使用www.bruce.com域名,開發你的網站,我使用 www.fankai.com開發我的網站,那么當然不希望我們的Hibernate相互干擾,所以就可以放在 EJB Class Loader級別來配置Hibernate。

    進一步闡述一下EJB Class Loader的問題:

    先再次強調一下,Hibernate和EJB,和App Server不存在兼容性問題,他們本來就是不相關的東西,就好像JDBC,相信沒有人會認為JDBC和EJB不兼容吧,Hibernate也是一樣,它 只和JDBC驅動,和數據庫有兼容性問題,而和EJB,和App Server完全是不搭界的兩回事。凡是認為Hibernate和EJB不兼容的人,其實是都是因為對EJB學習的不到家,把責任推到Hibernate 身上了。

    我前面的帖子提到過Class Loader的層次,這里不重復了,總之我們先來看看Class Loader的作用范圍:
    (#me: BootStrap Class Loader會加載ExtClassLoader, 并設置其parent為null
                  然后BootStrap Class Loader會加載AppClassLoader,并設置其parent為ExtClassLoader
                  然后ExtClassLoader加載,AppClassLoader再加載#)
    BootStrap Class Loader:
    >>>>> load JRE"lib"rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.jar

    Ext Class Loader:
    >>>>>load JRE"lib"ext目錄下的庫文件, load JRE"classes目錄下的類

    App Class Loader:
    >>>>>load CLASSPATH變量指定路徑下的類

    以上的load路徑都是寫死在JVM的C
    ++源代碼里面的,不能改變,詳細請見王森的《Java深度歷險》

    在一個特定的App Server上,Class Loader會繼續向下繼承,繼承的層次會根據不同的App Server有所不同,但是肯定不會變的就是:
    EJB Class Loader:
    >>>>>繼承自App Class Loader,繼承層次根據App Server有所不同,
    >>>>>一個EJB Class Loader它的load Class的范圍僅限于JAR或者EAR范圍之內。

    Web App Class Loader:
    >>>>>繼承自App Class Loader,繼承層次根據App Server有所不同,
    >>>>>一個Web App Class Loader:它的load Class的范圍在 WEB-INF"lib下的庫文件和WEB-INF"classes目錄下的class文件。

    Web App Class Loader很好理解,大家畢竟用的很多,App Server上的一個Web Application會創建一個Web App Class Loader的實例去負責load class,所以如果你想讓Hibernate只在這個Web Application內生效,把它放到WEB-INF"lib下去就好了。

    如果你把Hibernate放到了CLASSPATH變量指定的路徑下,而你在WEB-INF"lib也放了一份,那么Web App Class Loader由于load范圍所限,它會首先找到WEB-INF"lib下的那份Hibernate,按照它的配置來初始化Hibernate。

    如果你把Hibernate放到了CLASSPATH變量指定的路徑下,但你在WEB-INF"lib什么都沒有放,那么Web App Class Loader由于load范圍所限,它根本什么都找不到,于是它把load Hibernate的責任交給上一級的Class Loader,這樣直到App Class Loader,它找到了Hibernate,按照它的配置來初始化Hibernate。

    EJB Class Loader稍微復雜一點,不那么容易理解App Server會針對每一個EJB包文件創建一個EJB Class Loader的實例,例如:
    HelloRobbin.jar
    HelloBruce.jar

    當你把這兩個jar發布到App Server上以后,會創建兩個EJB Class Loader的實例,分別去load這兩個EJB包,比如說:
    CLEJB_Robbin是load HelloRobbin.jar的
    CLEJB_Bruce是load HelloBruce.jar的

    那么CLEJB_Robbin的load范圍就僅僅限于HelloRobbin.jar之內,它load不到HelloRobbin.jar之外的任何文件,當然它也load不到HelloBruce.jar。

    說到這里,我相信大家應該已經明白為什么EJB規范不允許EJB有IO操作了吧?因為EJB Class Loader根本找不到jar包之外的文件!!!
    (#me:這里是我疑問最大的地方,也是測試驗證的地方#)

    如果現在你想實現HelloRobbin.jar和HelloBruce.jar的互相調用,那么該怎么辦?他們使用了不同的EJB Class Loader,相互之間是找不到對方的。解決辦法就是使用EAR

    現在假設HelloRobbin.jar和HelloBruce.jar都使用了Hibernate,看看該怎么打包和發布:
    HelloEJB.ear
    |------ HelloRobbin.jar
    |------ HelloBruce.jar
    |------ Hibernate2.jar
    |------ pojo.jar (定義所有的持久對象和hbm文件的jar包)
    |------ cglib-asm.jar
    |------ commons-beanutils.jar
    |------ commons-collections.jar
    |------ commons-lang.jar
    |------ commons-logging.jar
    |------ dom4j.jar
    |------ odmg.jar
    |------ log4j.jar
    |------ jcs.jar
    |------ hibernate.properties
    |------ log4j.properties
    |------ cache.ccf
    |------ META-INF"application.xml (J2EE規范的要求,定義EAR包里面包括了哪幾個EJB)


    除此之外,按照EJB規范要求,HelloRobbin.jar和HelloBruce.jar還必須指出調用jar包之外的類庫的名稱,這需要在jar包的manifest文件中定義:
    HelloRobbin.jar
    |------ META-INF"MANIFEST.MF

    MANIFEST.MF中必須包括如下一行:
    Class-Path: log4j.jar hibernate2.jar cglib-asm.jar commons-beanutils.jar commons-collections.jar commons-lang.jar
    commons
    -logging.jar dom4j.jar jcs.jar odmg.jar jcs.jar pojo.jar

    這樣就OK了,當把HelloEJB.ear發布到App Server上以后,App Server創建一個EJB Class Loader實例load EAR包里面的EJB,再根據EJB的jar包里面的MANIFEST.MF指出的Class-Path去尋找相應的jar包之外的類庫。

    所以一個EAR包有點類似一個Web Application,EJB Class Loader的load范圍也就是EAR范圍之內,它load不到EAR之外的文件。除非把Hibernate定義到CLASSPATH指定的路徑下,在 這種情況下,EJB Class Loader找不到Hibernate,只能交給上一級的Class Loader,最后由App Class Loader找到Hibernate,進行初始化。

    沒有寫完,繼續說...

    由于EAR這樣load Class規則,假設Robbin和Bruce都在同一個Weblogic上運行自己的網站,而我們都不希望自己的程序里面的Hibernate配置被對方的搞亂掉,那么我們就可以這樣來做:
    Robbin's Website:

    Robbin.ear
    |-------- robbin.war (把Web Application打包)
    |-------- robbin.jar (把開發的EJB打包)
    |-------- Hibernate2.jar
    ..
    |-------- META-INF"application.xml


    Bruce
    's Website:

    Bruce.ear
    |-------- bruce.war (把Web Application打包)
    |-------- bruce.jar (把開發的EJB打包)
    |-------- Hibernate2.jar
    ..
    |-------- META-INF"application.xml

    這樣在同一個App Server上運行,就可以互相不干擾。

    ===============================================================
    至此,這個是引文,外加了部分個人的解釋。
    其中針對如下的話:
    我相信大家應該已經明白為什么EJB規范不允許EJB有IO操作了吧?因為EJB Class Loader根本找不到jar包之外的文件
    我感覺很疑惑,同時EJB規范似乎有大概如下描述:
    EJB模型不推薦或者禁止在EJB組件中讀取文件....

    為什么不允許讀取文件呢?是否真的找不到呢?
    我采用了兩種方式:
    (方式一)
    ${Class_Name}.
    class.getClassLoader().getResourceAsStream("${file}");
    file路徑方式:
    一種方式采用直接的絕對路徑
    一種方式采用相對于ear包的/jar包內

    (方式二)
    new File(${file})
    file路徑采用絕對路徑
    結果得到如下結論:
    方式一 如果采用getResourceAsStream的方式,無法訪問ear包之外的資源
    方式一采用絕對路徑的文件方式,貌似返回是null(記錄有點模糊了)
    方式二采用絕對路徑,絕對沒有問題

    我現在想,并不是真的不能訪問外部資源,而是其設計就是為了把classloaser的界限限制在jar包內或者ear內,而不相互干擾,因而在其規范中就是禁止或者不推薦讀取文件的方式了。

    posted on 2008-03-26 18:19 crazycy 閱讀(1232) 評論(0)  編輯  收藏 所屬分類: JavaSE語言

    主站蜘蛛池模板: av免费不卡国产观看| ww在线观视频免费观看| 免费在线观看污网站| 亚洲精品美女久久久久久久| 成人女人A级毛片免费软件| 亚洲日韩乱码久久久久久| 99re在线精品视频免费| 亚洲精品国产专区91在线| 国产免费女女脚奴视频网| 亚洲人成高清在线播放| 美女视频黄的全免费视频| 国产精品亚洲专区在线观看 | 亚洲精品动漫免费二区| 免费高清资源黄网站在线观看| 亚洲精品无码中文久久字幕| 免费看的成人yellow视频| 老司机福利在线免费观看| 亚洲午夜精品第一区二区8050| a级男女仿爱免费视频| 亚洲综合一区二区精品久久| 成人超污免费网站在线看| 特级毛片免费观看视频| 亚洲毛片αv无线播放一区 | 日韩吃奶摸下AA片免费观看| 亚洲精华国产精华精华液好用| 国产成人精品免费视频软件| 成人无码区免费A∨直播| 99久久精品国产亚洲| 午夜一级毛片免费视频| GOGOGO高清免费看韩国| 亚洲成a人不卡在线观看| 免费国产怡红院在线观看| 国产午夜成人免费看片无遮挡| 久久亚洲精品无码aⅴ大香| 日韩黄色免费观看| 老司机精品免费视频| 亚洲国产精品综合一区在线| 免费在线看片网站| 2020因为爱你带字幕免费观看全集| 久久人午夜亚洲精品无码区| 亚洲国产成人一区二区精品区|