Eclipse 试框架分析 Z PDE q行时的参数讑֮如下Q?/span> Eclipse.buildId=unknown java.version=1.4.2 java.vendor=Sun Microsystems Inc. BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=zh_CN Framework arguments: -version 3 -application org.eclipse.pde.junit.runtime.coretestapplication -testApplication org.softme.triones.runtime.framework -pdelaunch -port 3655 -testpluginname org.softme.triones.runtime -classnames org.softme.triones.runtime.TrionesRuntimeAllTests Command-line arguments: -version 3 -application org.eclipse.pde.junit.runtime.coretestapplication -testApplication org.softme.triones.runtime.framework -data D:\netshop\runtime-test-workspace -dev file:D:/netshop/sources/.metadata/.plugins/org.eclipse.pde.core/Trionse Runtime Test/dev.properties -pdelaunch -os win32 -ws win32 -arch x86 -nl zh_CN -clean -debug -consolelog -port 3655 -testpluginname org.softme.triones.runtime -classnames org.softme.triones.runtime.TrionesRuntimeAllTests
由参数配|可以看出, Eclipse PDE 中插件测试实际上是启动了 org.eclipse.pde.junit.runtime.coretestapplication q个应用Q而被试的应用通过参数 –testApplication 指定Q运行的参数通过 –dev file:?/dev.properties 来指定。我们先分析一?/span> dev.properties 文gQ?/span> org.softme.triones.runtime=bin org.softme.triones.sdk=bin org.eclipse.osgi=bin org.softme.triones.hello=bin com.opensymphony=bin org.softme.triones.turbine=bin q里配置需要加载的工作区插件和 class 路径?/span> |
通过对Eclipse试框架的研IӞ发现目前无法支持Triones框架的测试环境要求:
“测试框架由
org.eclipse.test
插g?/span>
org.eclipse.ant.optional.junit
D늻成?/span>
上面q两个工E可以从
dev.eclipse.org
资源库获取ƈ且已l包含在
eclipse-Automated-Tests.<buildid>.zip
文g中,可以?/span>
eclipse.org
下蝲面下蝲?/span>
试框架的当前版本ƈ不能?/span> PDE 集成环境兼容。如果你希望q行试Q那么你需要安装一套完整的目标 Eclipse 环境以便于测试框架能够检所有需要的内容。如果你准备Z个或多个 Eclipse 插g~写试Q那么你需要创Z个专门用于测试的独立的插件。这个测试插件将包含针对你正在开发的插g的所有测试,同时也定义了q些试的运行方式。?/span>
q样的情况下Q必重新考虑Triones框架的设计了?/span>
完成通过试E序调用 Triones Framework Runtime 插g的工作:
1?span style="FONT: 7pt 'Times New Roman'"> 只需要利?/span> Eclipse 的核心插件包?/span>
org.eclipse.core.runtime // Eclipse Plugin Runtime
org.eclipse.osgi // Eclipse OSGi Implemention
org.eclipse.update // Eclipse Plugin Loader/Updater
2?span style="FONT: 7pt 'Times New Roman'"> q_启动p动调用了 Triones 核心产品 org.softme.triones.runtime.framework 。部分输出如下:
Time to load bundles: 10
Starting application: 921
------------------------------------
Triones Framework: Started!
Triones Framework: Hello!
Triones Framework: Stoped!
------------------------------------
3?span style="FONT: 7pt 'Times New Roman'"> EclipseStarter 设计为应用运行完毕就自动调用 shutdown 使得q_退出, Triones 框架需要等?/span> ServletContext ?/span> Destroyed 事gQ因此必d此进行处理:
Ҏ一Q?/span> 创徏 Triones pȝdQƈ其挂v直到获得 ContextDestroyed 事g?/span>
Ҏ二: 扩展 EclipseStarter 修改q行E序Q不自动调用 shutdown Q等?/span> ContextDestroyed 事g?/span> TrionesContextListener 昑ּ调用 shutdown Ҏ?/span>
研究了一下午Q方案一g不太合理Q挂Lpȝq程Q?郁闷?/span>
?.
?/span>
考虑Ҏ?/span>
?
以上Q实现方案二Q?/span>
通过反射直接调用 EclipseStarter ?/span> startup(String[], Runable) ?/span> run(Object) Ҏ以启动^台ƈ保留在内存;关闭q_时调?/span> EclipseStarter ?/span> shutdown() Ҏ?/span>
问题Q?/span>
如何保留q程Q如何与
Context
环境交互Q?/span>
M能全部用反吧Q?/span>
ҎQ?/span> 通过反射取到 TrionesFramework 对象?/span>
步骤一Q?/span> ?/span> Triones Runtime 采取 分离接口模式
步骤二: 修改 launcher.EclipseLanucher 对象Q通过反射获取 TrionesFramework ?/span>
1) 需要通过 URLClassLoader 加蝲 Triones Runtime 插gQ?/span>
2) 需要修?/span> DevPath Q增?/span> Triones Runtime 的插件\径?/span>
3)
增加接口Q取?/span>
TrionesFramework
对象?/span>
实现了对
TrionesStarter
的反调用启动和关闭
Eclipse
q_Q但?/span>
?/span>
getFramework
Ҏ调用p|Q!Q!Q?/span>
Get the Triones framework....
java.lang.reflect.InvocationTargetException
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.TrionesEclipseLauncher.getFramework(TrionesEclipseLauncher.java:815)
?o:p>
Caused by: java.lang.NoClassDefFoundError: org/eclipse/core/runtime/Platform
at org.softme.triones.runtime.TrionesFramework.<init>(TrionesFramework.java:55)
at org.softme.triones.runtime.TrionesStarter.getFramework(TrionesStarter.java:52)
... 22 more
看来设计架构上还是出了问题,查一?/span>
URLClassLoader
的文:
StartupClassLoader
仅仅包含启动包的c\径,?/span>
Triones
必须所有类路径加蝲?/span>
context
中,才能够实?/span>
Context
Q?/span>
Servlet
Q与框架的交互?/span>
改进ҎQ设法?/span>
OSGi
c\径加载到
Context
路径中!
关于ClassLoader 问题的分析:
EclipeClassLoader 创徏:
获取ClassLoaderParent 的方法,使用?/SPAN>EclipseAdaptor
Adaptor ?/SPAN>getBundleClassLoaderParent() 如何d bundleClassLoaderParent?
如果使用了了boot Classloader ?/SPAN> ParentClassLoader 是新建的 bootQ这里分析看来应该?/SPAN>framework 或者系l的ClassLoader吧?/SPAN>
Ҏ以上的分析,?/SPAN>Triones的启动环境进行了调整Q?/SPAN>
1?/FONT>直接引用 org.eclipse.osgi 中的启动包,避免使用反射。注Q可以直接调?/SPAN>EclipseStarter.run(null) 了?/SPAN>
2?/FONT>?/SPAN>Triones Runtime 拆分成ؓ triones-core.jar Q包括主要的服务接口 ItrionesFramework {)?/SPAN> triones-runtime.jar (Triones Runtime Eclipse插g)?/SPAN>
3?/FONT>修改 Eclipse ?/SPAN> config.ini 配置?/SPAN>
# osgi classloader :
osgi.parentClassloader = fwk
Ҏ上面的分析, fwk 表示使用 FrameworkAdaptor ?/SPAN>ClassLoader 作ؓOSGi?/SPAN>parent classloader?/SPAN>
bundleClassLoaderParent = FrameworkAdaptor.class.getClassLoader();