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

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

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

    Equinox加載Bundle Class的實(shí)現(xiàn)

    對于想使用Equinox來構(gòu)建OSGi應(yīng)用的同學(xué)們而言,掌握Equinox是如何加載Bundle中的Class無疑是相當(dāng)重要的,這樣在碰到各類ClassNotFoundException的時(shí)候也就有底了,否則可能出現(xiàn)的ClassNotFoundException會(huì)多的讓你非常的頭疼,本文提取自《OSGi原理與最佳實(shí)踐》,介紹下equinox是如何來加載Bundle中的class的。

    Equinox在創(chuàng)建BundleClassLoader時(shí),首先獲取bundleclasspath,然后執(zhí)行createBCLPrevileged方法,此方法最后轉(zhuǎn)交由BaseData來創(chuàng)建ClassLoader

    BaseDate創(chuàng)建ClassLoader的關(guān)鍵代碼片段為:

        ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks();

        ClassLoader parent = adaptor.getBundleClassLoaderParent();

        BaseClassLoader cl = null;

        for (int i = 0; i < hooks.length && cl == null; i++)

           cl = hooks[i].createClassLoader(parent, delegate, domain, this, bundleclasspath);

        if (cl == null)

           cl = new DefaultClassLoader(parent, delegate, domain, this, bundleclasspath);

        return cl;

    Equinox中,默認(rèn)的情況下adaptor.getBundleClassLoaderParent返回的為bootstrap  classloader,可通過修改啟動(dòng)的osgi.parentClassLoader來改變這個(gè)parent classloader,默認(rèn)值采用的boot,可選的其他值有:appextfwkapp對應(yīng)的為SystemClassLoaderext對應(yīng)的為SystemClassLoaderparentfwk對應(yīng)的為啟動(dòng)EquinoxClassLoaderClassLoadingHookcreateClassLoader的時(shí)候都沒有做動(dòng)作,因此最后ClassLoader都是通過創(chuàng)建DefaultClassLoader對象來構(gòu)建的,其中parent參數(shù)為nulldelegate參數(shù)為BundleLoader實(shí)例,bundleclasspath參數(shù)為bundleclasspath

    經(jīng)過以上步驟后,完成了ClassLoader的創(chuàng)建,可以開始加載class了,根據(jù)上面上述,BundleClass就由DefaultClassLoader來完成了。

    查看DefaultClassLoaderloadClass代碼,發(fā)現(xiàn)真正的加載class的過程是轉(zhuǎn)為調(diào)用了delegatefindClass來完成的,delegate參數(shù)對應(yīng)的為BundleLoader實(shí)例,轉(zhuǎn)為跟蹤BundleLoaderfindClass方法。

    BundleLoaderfindClass方法的代碼片段:

        if (checkParent && parentCL != null && name.startsWith(JAVA_PACKAGE))

           return parentCL.loadClass(name);

    從以上這個(gè)代碼片段,可以看到,Equinoxjava.開頭的類轉(zhuǎn)交給了parent classloader去加載,這也意味著沒必要在系統(tǒng)中提供對外export java.開頭的package

    如果不是java.開頭的類,則交由findClassInternal方法來完成加載。

    findClassInternal方法遵循的為OSGi規(guī)范中定義的Class的加載順序,不過仍然稍有改動(dòng):

    1)         判斷是否交由parent classloader去完成加載

    在啟動(dòng)Equinox時(shí),Equinox會(huì)讀取org.osgi.framework.bootdelegation屬性,該屬性對應(yīng)配置的為需要從parent classloader中加載的package,如值配置的為*,說明所有的都從parent classloader中加載,如值配置的為具體的package,那么則放入bootDelegation集合;如配置的為帶通配符的package,那么則放入bootDelegationStems集合。

    判斷時(shí)Equinox首先判斷是否所有的都從parent classloader中加載,如是則從parent classloader中加載;

    如需要加載的類的package位于bootDelegationbootDelegationStems集合中,那么同樣從parent classloader中加載。

    如不從parent classloader中加載,則進(jìn)入下面的步驟。

    2)         嘗試調(diào)用Equinox提供的ClassLoaderDelegateHook的擴(kuò)展來加載

    Equinox對外提供了ClassLoaderDelegateHook的接口擴(kuò)展,可編寫ClassLoaderDelegateHook的實(shí)現(xiàn),注冊到Framework中,那么當(dāng)有Class需要加載等動(dòng)作時(shí)都會(huì)得到通知。

    在默認(rèn)情況下,Equinox中沒有ClassLoaderDelegateHook的實(shí)現(xiàn),因此繼續(xù)下面的步驟。

    3)         判斷是否在import-package中,如在則交由相應(yīng)的PackageSource去加載

    根據(jù)Bundle配置的import-package,判斷目前需要加載的類是否在import-package中,如在則交由對應(yīng)的PackageSource進(jìn)行加載,PackageSource在加載時(shí)即直接交由對應(yīng)的Bundleclassloader去加載,如加載的類的packageimport-package中,但加載后仍然沒有找到Class,則直接拋出ClassNotFoundException,如加載到,則直接返回。

    如所需要加載的類不的package不在import-package中,則繼續(xù)下面的步驟。

    4)         嘗試從require-bundle中加載

    嘗試使用require-bundle來加載,如加載到,則直接返回,如加載不到,則繼續(xù)下面的步驟。

    5)         嘗試從當(dāng)前Bundle中加載

    直到經(jīng)過以上步驟的嘗試,才嘗試由當(dāng)前Bundle中加載,當(dāng)前Bundle加載的方法即從Bundle-Classpath或當(dāng)前BundleFragment中查找相應(yīng)名稱的class文件,并讀取該文件進(jìn)行加載,如class文件已加載,則進(jìn)行緩存,再次加載時(shí)則不需要查找和解析class文件。

    如從當(dāng)前Bundle中仍然未找到所需的類,則繼續(xù)下面的步驟。

    6)         嘗試從DynamicImport-Package中加載

    判斷需要找的類的package是否在DynamicImport-Package中,如果在,則交由相應(yīng)的PackageSource進(jìn)行加載,如PackageSource中加載不到,則拋出ClassNotFoundException;如不在DynamicImport-Package中,則繼續(xù)下面的步驟。

    7)         再次嘗試調(diào)用Equinox提供的ClassLoaderDelegateHook的擴(kuò)展來加載

    這步和第2)步相同,因此在默認(rèn)情況下繼續(xù)下面的步驟。

    8)         嘗試使用eclipsebuddy機(jī)制來加載

    Buddy機(jī)制是Eclipse的擴(kuò)展,并不符合OSGi規(guī)范,因此在此不做深入分析。

    9)         判斷一定的條件,如符合則從parent classloader中加載

    判斷的條件為:parent classloader不為null、不從parent classloader中加載、Equinox的向后兼容屬性(osgi.compatibility.bootdelegation)為true以及jvmbug class,如滿足以上條件,則嘗試從parent classloader中加載。

    如經(jīng)過以上所有步驟后,仍然未找到需要加載的class,則拋出ClassNotFoundException

    從上面的代碼分析中,在Equinox中可以通過osgi.parentClassLoaderorg.osgi.framework.bootdelegation來控制從Bundle ClassLoader外來加載Class,這對于集成Equinox其他容器而言,非常有用,另外,還可以通過實(shí)現(xiàn)ClassLoaderDelegateHook來改變Class的加載。

    posted on 2009-05-10 17:25 BlueDavy 閱讀(6683) 評論(12)  編輯  收藏 所屬分類: OSGi、SOA、SCA

    評論

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-10 20:15 galaxystar

    頂一下畢老大  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-16 22:31 Kane

    應(yīng)該附帶把Equniox的findLibrary一起講了
    :)  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn)[未登錄] 2009-05-20 16:57 jame

    今天剛好遇到一個(gè)Bundle中調(diào)用javax.xml的問題,一至報(bào)ClassNotFoundException:javax.xml.parsers.SAXParserFactory錯(cuò)誤.

    http://docs.codehaus.org/display/JETTY/OSGi+Tips
    中是這么說的:
    All of these, except for javax.mail, org.apache.tools.ant. and org.eclipse.jdt. can all be found in the jvm's rt.jar. In Equinox, by default, these system packages from the system classloader are not exposed inside the OSGi framework. So, we need to expose them by using this setup in the config.ini:

    org.osgi.framework.system.packages=javax.naming, javax.naming.directory, javax.naming.spi, javax.management, javax.management.loading, javax.management.modelmbean, javax.net, javax.net.ssl, javax.crypto, javax.crypto.interfaces, javax.crypto.spec, javax.security.auth, javax.security.auth.spi, javax.security.auth.callback, javax.security.auth.login, javax.security.cert, javax.xml.parsers, javax.xml.xpath, javax.xml.transform.sax, javax.xml.transform.dom, javax.xml.namespace, javax.xml.transform, javax.xml.transform.stream, javax.xml.validation, org.xml.sax, org.xml.sax.helpers, org.xml.sax.ext, com.sun.org.apache.xalan.internal, com.sun.org.apache.xalan.internal.res, com.sun.org.apache.xml.internal.utils, com.sun.org.apache.xpath.internal, com.sun.org.apache.xpath.internal.jaxp, com.sun.org.apache.xpath.internal.objects, com.sun.org.apache.xml.internal, org.w3c.dom, org.w3c.dom.traversal, org.w3c.dom.ls, javax.sql, javax.transaction, sun.misc

    但加上這些package后還是沒有解決....最后發(fā)現(xiàn)要加
    org.osgi.framework.bootdelegation=*這句.

    找了一個(gè)下午,汗.......

    BlueDavy什么時(shí)候能詳細(xì)說一下config.ini中主要配置的作用嗎?
    如:http://tieba.baidu.com/f?kz=76392347這里列出來的這些...
    期待....
      回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-20 17:52 Kane

    import javax.* in Import-package header  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn)[未登錄] 2009-05-21 09:42 jame

    @Kane
    Import-Package: javax.xml;version="1.3.0",
    javax.xml.datatype;version="1.3.0",
    javax.xml.namespace;version="1.3.0",
    javax.xml.parsers;version="1.3.0",
    org.osgi.framework

    啟動(dòng)時(shí)報(bào):
    org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Import-Package: javax.xml; version="1.3.0"

    正常的java文件中是能import javax.xml.parsers.*;
    應(yīng)該是OSGI ClassLoader的特殊性.

    之前在Eclipse3.4中測試是會(huì)沒這個(gè)問題的,當(dāng)通過命令行方式來啟動(dòng)equinox時(shí)才遇到這個(gè)問題.
    按此BLOG中講的在configuration\config.ini中添加org.osgi.framework.bootdelegation=*解決問題  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-21 10:49 BlueDavy

    @jame
    ...配置成*的話,所有類都會(huì)從bootstrap classloader里裝載的,應(yīng)該只配javax.*
      回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-21 11:00 Kane

    @jame
    org.osgi.framework.bootdelegation=*并不是好的解決辦法,它讓OSGi的classloader的模塊化特性丟失了。
    我覺得通過指定org.osgi.framework.system.packages是更好的辦法,比如
    -Dorg.osgi.framework.system.packages=javax.accessibility,javax.activation,javax.activity,javax.annotation, javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.i mageio.event,javax.imageio.metadata...
      回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn)[未登錄] 2009-05-21 13:19 jame

    @Kane
    這種方式與在config.ini配置有區(qū)別嗎?
    我配置在config.ini中的時(shí)候好象不想作用?

    @BlueDavy
    如果一個(gè)正在運(yùn)行OSGI的項(xiàng)目中新增一個(gè)Bundle,但這個(gè)新增的Bundle需要用到j(luò)ava以外package中的類,有沒有其他更好的方法?如果改配置那得重啟整個(gè)項(xiàng)目了....(就如修改Eclipse中某些配置后需要重啟才能生效?)
      回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn)[未登錄] 2009-05-21 13:28 jame

    @Kane
    這是我run.bat中的內(nèi)容,剛才測試這種方法好象不能解決這個(gè)問題.是不是還是設(shè)置其他項(xiàng)?(config.ini org.osgi.framework.bootdelegation=javax.*,org.*除外)

    @echo off
    java -Xms128m -Xmx512m -Dorg.osgi.service.http.port=8111 -Dorg.osgi.framework.system.packages=javax.naming,javax.naming.directory,javax.naming.spi... -jar org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar -configuration ../configuration -console  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-21 15:15 BlueDavy

    @jame
    如果新增的bundle需要用到j(luò)ava以外package的類,通常做法是把依賴的類也打到一個(gè)bundle,然后對外export..
      回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn) 2009-05-21 15:16 BlueDavy

    @jame
    在Equinox中,另外一種方法就是自己實(shí)現(xiàn)ClassLoadingHook,就可以自己控制了。  回復(fù)  更多評論   

    # re: Equinox加載Bundle Class的實(shí)現(xiàn)[未登錄] 2009-05-21 16:55 jame

    @BlueDavy
    謝謝指點(diǎn)...

    新書什么時(shí)候出版,期待....  回復(fù)  更多評論   

    公告

     









    feedsky
    抓蝦
    google reader
    鮮果

    導(dǎo)航

    <2009年5月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    統(tǒng)計(jì)

    隨筆分類

    隨筆檔案

    文章檔案

    Blogger's

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品麻豆av| 国产亚洲午夜高清国产拍精品 | 丝袜捆绑调教视频免费区| 国产免费AV片在线观看 | 亚洲成年人免费网站| 四虎在线免费播放| 亚洲精品成a人在线观看| 久久精品国产96精品亚洲| 国产成人精品日本亚洲18图| 精品国产亚洲一区二区三区在线观看 | 久久一本岛在免费线观看2020| 又黄又爽又成人免费视频| 四虎永久免费地址在线网站| 亚洲区小说区图片区QVOD| 亚洲国产精品成人精品软件| 国产亚洲精品成人久久网站| 久久精品国产大片免费观看| 成人超污免费网站在线看| 中文亚洲AV片不卡在线观看| 亚洲一区中文字幕在线观看| 黄色a级片免费看| 2019中文字幕在线电影免费| 国产国产人免费视频成69大陆 | 亚洲av午夜精品无码专区| 全黄A免费一级毛片| 6080午夜一级毛片免费看6080夜福利| 永久久久免费浮力影院| 亚洲成A人片777777| 亚洲色www永久网站| 免费无码又爽又刺激网站直播| 嫩草影院在线免费观看| 久久精品国产亚洲网站| 亚洲JLZZJLZZ少妇| 无码人妻一区二区三区免费n鬼沢| 日韩一级视频免费观看| 亚洲一区免费观看| 九一在线完整视频免费观看| 一二三四免费观看在线视频中文版| 国产亚洲老熟女视频| 亚洲国产成人手机在线观看| 99国产精品视频免费观看|