根据插件ID(Namespace)和路径找出视图源文件
|
主要任务,根据插件
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%
。
不得窥道门,不得悟佛门,不得入窄门,实乃破门。