破門點(diǎn)滴(Java技術(shù)版)

          在日常學(xué)習(xí)和工作中記錄

            BlogJava :: 首頁 ::  :: 聚合  :: 管理
            15 Posts :: 7 Stories :: 36 Comments :: 0 Trackbacks
          根據(jù)插件ID(Namespace)和路徑找出視圖源文件
          2004-12-23 19:58:14

          主要任務(wù),根據(jù)插件 ID Namespace )和路徑找出視圖源文件。

          基本上完成文件的讀取:

          ????????????? Bundle nsbundle = Platform.getBundle(pluginId);? // 獲取 bundle( 插件 )

          ????????????? URL url = nsbundle.getEntry( target );???????????? // ?? 獲取資源路徑

          ????????????? url = Platform.asLocalURL( url );???????????? // 返回物理文件路徑 URL

          ?

          以上參數(shù)說明:

          pluginId 插件 ID ??????????????????? 例如: org.softme.triones.hello

          ????????????? target?? 資源文件相對(duì)路徑 ?? 例如: templates/index.vm

          ?

          結(jié)果范例:

          file:/D:/netshop/triones/plugins/org.softme.triones.hello_0.0.1/templates/index. vm

          其中: file:/D:/netshop/triones/ Triones 系統(tǒng)安裝路徑。

          第二步:創(chuàng)建 netshop web 應(yīng)用

          問題出現(xiàn):

          2004-12-23 19:46:38 StandardContext[/netshop]Exception sending context initialized event to listener instance of class org.softme.triones.TrionesContextListener

          java.lang.Error: factory already defined

          ???????? at java.net.URL.setURLStreamHandlerFactory(Unknown Source)

          ???????? at org.eclipse.osgi.framework.internal.core.Framework.initialize(Framework.java:154)

          ???????? at org.eclipse.osgi.framework.internal.core.Framework.<init>(Framework.java:95)

          ???????? at org.eclipse.osgi.framework.internal.core.OSGi.createFramework(OSGi.java:90)

          ???????? at org.eclipse.osgi.framework.internal.core.OSGi.<init>(OSGi.java:31)

          ???????? at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:215)

          ???????? at org.softme.triones.launcher.TrionesStarter.basicRun(TrionesStarter.java:1063)

          ???????? at org.softme.triones.launcher.TrionesStarter.launch(TrionesStarter.java:672)

          ???????? at org.softme.triones.TrionesContextListener.contextInitialized(TrionesContextListener.java:51)

          ?

          原因:在一個(gè)虛擬機(jī)中,該方法只能被調(diào)用一次。

          參考:

          java.net.URL 是各種協(xié)議,包括已知和未知的入口,通過 URL.setURLStreamHandlerFactory(URLStreamHandlerFactory handlerFactory) 方法可以設(shè)置新的協(xié)議處理器的工廠類的實(shí)例,在一個(gè)虛擬機(jī)中,該方法只能被調(diào)用一次。除了利用這種方式向系統(tǒng)注冊(cè)外,還可以通過設(shè)置系統(tǒng)屬性 java.handler.protol.pkg 或者 sun.net.www.protocol 來實(shí)現(xiàn)注冊(cè)。系統(tǒng)會(huì)按照 setURLStreamHandlerFactory() java.handler.protol.pkg sun.net.www.protocol 三種方法,從高優(yōu)先級(jí)到低優(yōu)先級(jí)的進(jìn)行搜索特定協(xié)議對(duì)應(yīng)的處理器。 java.handler.protol.pkg 對(duì)應(yīng)的值的構(gòu)成是用 | 分隔的各個(gè)協(xié)議處理器的類,格式為 ..Handler | ..Handler | ... sun.net.www.protocol 的設(shè)置方式是 sun.net.www.protocol..Handler ,這個(gè) sun.net.www.protocol..Handler 會(huì)被追加到第二種方式得到的值后面,然后逐個(gè)加載。注意,設(shè)置屬性的時(shí)候,只需要寫上 handler package protocol 之前的部分,例如對(duì)于 myProtocol 協(xié)議,則, myProtocol 的處理器的類命名格式為 myPackage.myProtocol.Handler ,或者是 sun.net.www.protocol.myProtocol.Handler, 設(shè)置屬性的時(shí)候,只需要寫上 myPackage 即可,剩下的部分, URL 類會(huì)自動(dòng)處理的。

          ?

          看樣子必須改回用反射來初始化框架了。

          改回成反射調(diào)用的模式依然出現(xiàn)以上錯(cuò)誤,看來可能是與 tomcat 發(fā)生了沖突,先下 tomcat 的源碼等明天查查看。

          果然,發(fā)現(xiàn) Tomcat 已經(jīng)調(diào)用了此方法: org.apache.catalina.loader.WebappLoader

          // Register a stream handler factory for the JNDI protocol

          ??????? URLStreamHandlerFactory streamHandlerFactory =

          ??????????? new DirContextURLStreamHandlerFactory();

          ??????? if (first) {

          ??????????? first = false;

          ??????????? try {

          ??????????????? URL.setURLStreamHandlerFactory(streamHandlerFactory);

          ??????????? } catch (Exception e) {

          ??????????????? // Log and continue anyway, this is not critical

          ??????????????? log.error("Error registering jndi stream handler", e);

          ??????????? } catch (Throwable t) {

          ??????????????? // This is likely a dual registration

          ??????????????? log.info("Dual registration of jndi stream handler: "

          ?????????????? ??????????+ t.getMessage());

          ??????????? }

          ??????? }

          ?

          嘗試將 Eclipse OSGi Framework 對(duì)象進(jìn)行更改:

          org.eclipse.osgi.framework.internal.core.Framework

          initialize() 方法,跳過二次注冊(cè) setURLStreamHandlerFactory 的錯(cuò)誤:

          /* install URLStreamHandlerFactory */

          ?????????????????? try{

          ??????????????????????????? URL.setURLStreamHandlerFactory(new

          ?StreamHandlerFactory(systemBundle.context, adaptor));

          ?????????????????? } catch (Throwable t) {

          ??????????????????????????? // This is likely a dual registration

          ??????????????????????????? if (Debug.DEBUG && Debug.DEBUG_GENERAL)

          ???????????????????????????????????? System.out.println("Dual registration of jndi stream handler: "

          ? ???????????????????+ t.getMessage());

          ?????????????????? }

          ?

          運(yùn)行出現(xiàn)錯(cuò)誤, Eclipse 無法加載插件:

          j ava.net.MalformedURLException: unknown protocol: reference

          ???????? at java.net.URL.<init>(Unknown Source)

          ???????? at org.eclipse.core.runtime.adaptor.EclipseStarter.searchForBundle(EclipseStarter.java:366)

          ???????? at org.eclipse.core.runtime.adaptor.EclipseStarter.getInitialBundles(EclipseStarter.java:466)

          ???????? at org.eclipse.core.runtime.adaptor.EclipseStarter.loadBasicBundles(EclipseStarter.java:418)

          ???????? at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:222)

          ???????? at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

          ???????? at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

          ???????? at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

          ???????? at java.lang.reflect.Method.invoke(Unknown Source)

          ???????? at org.softme.triones.launcher.TrionesInvokeStarter.basicRun(TrionesInvokeStarter.java:342)

          ???????? at org.softme.triones.launcher.TrionesInvokeStarter.launch(TrionesInvokeStarter.java:899)

          ???????? at org.softme.triones.TrionesContextListener.

          ?

          只能先研究以上參考中更新 protocol 注冊(cè)的第二種或第三種方法了。

          Eclipse 采用了 URLStreamHandlerProxy 的代理機(jī)制來處理,實(shí)際的服務(wù)定義在 OSGi service org.osgi.service.url. URLStreamHandlerService 實(shí)現(xiàn)中。解決了 Java JVM 對(duì) URLStreamHandler 進(jìn)行緩存而不能支持動(dòng)態(tài)加載的問題。

          因此,看來不能夠去掉 Eclipse 中對(duì) URL. setURLStreamHandlerFactory 的調(diào)用。

          ?

          解決辦法呢? ………………………………………….????????????????????????

          ?

          討論:

          方案一:在 JVM URL 協(xié)議注冊(cè)機(jī)制中尋求其他入口點(diǎn)。

          困難度 100 %: JVM 協(xié)議注冊(cè)的第二種和第三種方法都無法支持 Eclipse 的入口。

          因?yàn)?/span> Eclipse 通過對(duì) Factory 的擴(kuò)展支持了協(xié)議處理器( Handler )的動(dòng)態(tài)加載,以及嵌入了 OSGi 服務(wù)機(jī)制,所以無法采取其他入口實(shí)現(xiàn) Eclipse 加載機(jī)制。

          方案二:修改 Eclipse 框架,避開 setURLStreamHandlerFactory 的調(diào)用。

          困難度 100% :原因同上。

          方案三:修改 JRE java.net.URL 對(duì)象,允許多 factory 設(shè)置。

          困難度 10%



          不得窺道門,不得悟佛門,不得入窄門,實(shí)乃破門。
          posted on 2006-03-27 10:29 破門 閱讀(799) 評(píng)論(0)  編輯  收藏 所屬分類: Triones
          主站蜘蛛池模板: 华坪县| 高要市| 徐州市| 太谷县| 乃东县| 清苑县| 桓台县| 龙海市| 临江市| 邯郸县| 商河县| 抚顺市| 克拉玛依市| 上虞市| 武义县| 维西| 鹤壁市| 广东省| 淮南市| 沁源县| 化州市| 徐水县| 韶山市| 明水县| 潼关县| 行唐县| 虞城县| 车致| 沈丘县| 广南县| 札达县| 军事| 香港 | 泰安市| 宜昌市| 巴南区| 延边| 商南县| 长沙县| 墨脱县| 茶陵县|