破門點滴(Java技術版)

          在日常學習和工作中記錄

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

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

          基本上完成文件的讀取:

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

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

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

          ?

          以上參數說明:

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

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

          ?

          結果范例:

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

          其中: file:/D:/netshop/triones/ Triones 系統安裝路徑。

          第二步:創建 netshop web 應用

          問題出現:

          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)

          ?

          原因:在一個虛擬機中,該方法只能被調用一次。

          參考:

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

          ?

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

          改回成反射調用的模式依然出現以上錯誤,看來可能是與 tomcat 發生了沖突,先下 tomcat 的源碼等明天查查看。

          果然,發現 Tomcat 已經調用了此方法: 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 對象進行更改:

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

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

          /* 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());

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

          ?

          運行出現錯誤, 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 注冊的第二種或第三種方法了。

          Eclipse 采用了 URLStreamHandlerProxy 的代理機制來處理,實際的服務定義在 OSGi service org.osgi.service.url. URLStreamHandlerService 實現中。解決了 Java JVM URLStreamHandler 進行緩存而不能支持動態加載的問題。

          因此,看來不能夠去掉 Eclipse 中對 URL. setURLStreamHandlerFactory 的調用。

          ?

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

          ?

          討論:

          方案一:在 JVM URL 協議注冊機制中尋求其他入口點。

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

          因為 Eclipse 通過對 Factory 的擴展支持了協議處理器( Handler )的動態加載,以及嵌入了 OSGi 服務機制,所以無法采取其他入口實現 Eclipse 加載機制。

          方案二:修改 Eclipse 框架,避開 setURLStreamHandlerFactory 的調用。

          困難度 100% :原因同上。

          方案三:修改 JRE java.net.URL 對象,允許多 factory 設置。

          困難度 10%



          不得窺道門,不得悟佛門,不得入窄門,實乃破門。
          posted on 2006-03-27 10:29 破門 閱讀(799) 評論(0)  編輯  收藏 所屬分類: Triones
          主站蜘蛛池模板: 武威市| 井冈山市| 望城县| 遂宁市| 任丘市| 丰城市| 古蔺县| 安化县| 孟州市| 犍为县| 封丘县| 黑水县| 德兴市| 北票市| 峨眉山市| 长寿区| 章丘市| 蒲城县| 宜宾县| 津南区| 桓仁| 福清市| 门源| 南汇区| 宜宾县| 六盘水市| 临漳县| 阿巴嘎旗| 新密市| 株洲县| 思南县| 泽库县| 石林| 吴忠市| 巴楚县| 上林县| 郴州市| 修水县| 蛟河市| 育儿| 贵南县|