- 浏览: 144128 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
EclipseEye:
fair_jm 写道不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程 -
fair_jm:
不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程
双击eclipse安装目录下的eclipse.exe运行后,会加载同一目录下的eclipse.ini文件(对应RCP项目也是一样,在RCP的安装目录下会有一个RCPName.ini文件):
这里要说一下,Eclipse的JVM启动的时候找JRE的顺序是:
如果eclipse.ini中配置了-vm参数,那么则使用这个参数指定的JRE(jvm.dll库路径);
否则,查看eclipse安装目录下是否有JRE文件夹,如果有的话就使用这个JRE;
否则,去系统注册表中查找安装的JRE,如果还找不到就报错。
所以如果不想卸载掉其他的JDK的话,可以有两种方式:
直接把要使用的JRE文件夹拷贝到Eclipse目录下
修改eclipse.ini文件,添加-vm参数,指定要运行的虚拟机的地址,形如:
-vm
C:\Program Files\Java\jdk1.6.0_12\bin\..\jre\bin\client\jvm.dll
(在eclipse.ini文件中添加配置项时,有空格就换行,不然会当成无效参数)
eclipse.ini文件中:
-startup 指定启动的入口为:安装目录下plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
会加载该jar包中的org.eclipse.equinox.launcher.Main.class类并调用其main(String)完成app的启动过程
通过一个Exception.printStackTrace()方法来看一下Eclipse的大概启动过程:
图中是打印的状态栈,从下往上就是整个Eclipse(或者说RCP程序)的加载和启动过程,一直到App的启动。
下面来通过源代码,具体说明:
从org.eclipse.equinox.launcher.Main这个类开始:
在Main这个类的main()方法中下一个断的,调试状态启动Eclipse中的RCP程序就可以跟踪这个RCP启动的过程(Eclipse的过程也是类似的,其实EclipseIDE就是一个巨型的RCP):
然后看一下run()方法:
下面针对其中的几个重要方法进行说明:
processConfiguration:处理配置信息
config.ini文件内容(举例)
getInstallLocation() 获取当前安装路径
getBootPath() 获取启动路径列表
setupJNI()启动JNIBridge,加载dll类库
invokeFramework()启动Equinox框架
接下来看一下EclipseStarter.run()
先到这里,有空继续分析
-startup plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar --launcher.library plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.100.v20110502 -product org.eclipse.epp.package.rcp.product --launcher.defaultAction openFile -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256M -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m
这里要说一下,Eclipse的JVM启动的时候找JRE的顺序是:
如果eclipse.ini中配置了-vm参数,那么则使用这个参数指定的JRE(jvm.dll库路径);
否则,查看eclipse安装目录下是否有JRE文件夹,如果有的话就使用这个JRE;
否则,去系统注册表中查找安装的JRE,如果还找不到就报错。
所以如果不想卸载掉其他的JDK的话,可以有两种方式:
直接把要使用的JRE文件夹拷贝到Eclipse目录下
修改eclipse.ini文件,添加-vm参数,指定要运行的虚拟机的地址,形如:
-vm
C:\Program Files\Java\jdk1.6.0_12\bin\..\jre\bin\client\jvm.dll
(在eclipse.ini文件中添加配置项时,有空格就换行,不然会当成无效参数)
eclipse.ini文件中:
-startup 指定启动的入口为:安装目录下plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
会加载该jar包中的org.eclipse.equinox.launcher.Main.class类并调用其main(String)完成app的启动过程
通过一个Exception.printStackTrace()方法来看一下Eclipse的大概启动过程:
图中是打印的状态栈,从下往上就是整个Eclipse(或者说RCP程序)的加载和启动过程,一直到App的启动。
下面来通过源代码,具体说明:
从org.eclipse.equinox.launcher.Main这个类开始:
在Main这个类的main()方法中下一个断的,调试状态启动Eclipse中的RCP程序就可以跟踪这个RCP启动的过程(Eclipse的过程也是类似的,其实EclipseIDE就是一个巨型的RCP):
public static void main(String[] args) { int result = 0; ... result = new Main().run(args); ... }
然后看一下run()方法:
public int run(String[] args) { ... basicRun(args); ... }主要实现就在basicRun()方法中:
protected void basicRun(String[] args) throws Exception { //记录启动启动时间 System.getProperties().put("eclipse.startTime", Long.toString(System.currentTimeMillis())); //$NON-NLS-1$ commands = args; //处理Command参数,并根据Command参数设置默认属性 String[] passThruArgs = processCommandLine(args); if (!debug) // debug can be specified as system property as well debug = System.getProperty(PROP_DEBUG) != null; setupVMProperties();//将VM参数写入到System.Properties中 processConfiguration();//加载配置信息 getInstallLocation();//获取安装路径,这里调用一下是为了确保InstallLocation被初始化 // locate boot plugin (may return -dev mode variations) URL[] bootPath = getBootPath(bootLocation);//获取启动路径列表 setupJNI(bootPath);//启动JNIBridge,加载dll类库 //检查JDK版本 if (!checkVersion(System.getProperty("java.version"), System.getProperty(PROP_REQUIRED_JAVA_VERSION))) return; //检查配置信息 if (!checkConfigurationLocation(configurationLocation)) return; setSecurityPolicy(bootPath);//设置安全策略 handleSplash(bootPath);//启动闪屏,就是Eclipse(或RCP启动时IDE打开前带有进度条的界面) beforeFwkInvocation(); invokeFramework(passThruArgs, bootPath);//加载框架(前面的工作都是辅助,这个才是加载框架的核心) }
下面针对其中的几个重要方法进行说明:
processConfiguration:处理配置信息
private void processConfiguration() { URL baseConfigurationLocation = null; Properties baseConfiguration = null; //在系统的配置文件中,键值对形如: //osgi.configuration.area=file:/E:/eclipse-rcp-indigo-SR2-win32/eclipse/configuration/ if (System.getProperty(PROP_CONFIG_AREA) == null) { String baseLocation = System.getProperty(PROP_BASE_CONFIG_AREA); if (baseLocation != null) baseConfigurationLocation = buildURL(baseLocation, true); if (baseConfigurationLocation == null) try { //在并没指定参数的情况下,将会把Location指定到: 安装目录/configuration baseConfigurationLocation = new URL(getInstallLocation(), CONFIG_DIR); } catch (MalformedURLException e) { // leave baseConfigurationLocation null } //加载目录下的config.ini文件,对其文件中的键值对 配置信息 baseConfiguration = loadConfiguration(baseConfigurationLocation); ... ... } Properties configuration = baseConfiguration; if (configuration == null || !getConfigurationLocation().equals(baseConfigurationLocation)) configuration = loadConfiguration(getConfigurationLocation()); //把配置信息合并到System.getProperties()中 mergeProperties(System.getProperties(), configuration, null); ... ...
config.ini文件内容(举例)
#This configuration file was written by: org.eclipse.equinox.internal.frameworkadmin.equinox.EquinoxFwConfigFileParser #Sun Feb 17 13:24:53 CST 2013 org.eclipse.update.reconcile=false eclipse.p2.profile=epp.package.rcp osgi.instance.area.default=@user.home/workspace osgi.framework=file\:plugins/org.eclipse.osgi_3.7.2.v20120110-1415.jar equinox.use.ds=true eclipse.buildId=M20120208-0800 osgi.bundles=reference\:file\:org.eclipse.equinox.simpleconfigurator_1.0.200.v20110815-1438.jar@1\:start org.eclipse.equinox.simpleconfigurator.configUrl=file\:org.eclipse.equinox.simpleconfigurator/bundles.info eclipse.product=org.eclipse.platform.ide osgi.splashPath=platform\:/base/plugins/org.eclipse.platform osgi.framework.extensions= osgi.bundles.defaultStartLevel=4 eclipse.application=org.eclipse.ui.ide.workbench eclipse.p2.data.area=@config.dir/../p2/
getInstallLocation() 获取当前安装路径
private URL getInstallLocation() { if (installLocation != null) return installLocation; //从系统配置信息中获取安装路径,有的话就直接返回 String installArea = System.getProperty(PROP_INSTALL_AREA); if (installArea != null) { installLocation = buildURL(installArea, true); System.getProperties().put(PROP_INSTALL_AREA, installLocation.toExternalForm()); return installLocation; } //如果没有,则通过获取main类包的路径换算出安装路径 ProtectionDomain domain = Main.class.getProtectionDomain(); CodeSource source = null; URL result = null; source = domain.getCodeSource(); result = source.getLocation(); String path = decode(result.getFile()); ... ... installLocation = new URL(result.getProtocol(), result.getHost(), result.getPort(), path); return installLocation; }
getBootPath() 获取启动路径列表
protected URL[] getBootPath(String base) throws IOException { URL url = null; if (base != null) { url = buildURL(base, true); } else { // search in the root location url = getInstallLocation(); String path = new File(url.getFile(), "plugins").toString(); path = searchFor(framework, path); if (url.getProtocol().equals("file")) url = new File(path).toURL(); else url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); } //键值对,形如:osgi.framework=file:/e:/eclipse/plugins/org.eclipse.osgi_3.7.2.v20120110-1415.jar //指定osgi jar的路径 if (System.getProperty(PROP_FRAMEWORK) == null) System.getProperties().put(PROP_FRAMEWORK, url.toExternalForm()); //获取启动路径列表 URL[] result = getDevPath(url); return result; }
setupJNI()启动JNIBridge,加载dll类库
private void setupJNI(URL[] defaultPath) { String libPath = null; /** * 获取--launcher.library的路径, 形如: * --launcher.library * plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.100.v20110502 */ if (library != null) { File lib = new File(library); if (lib.isDirectory()) { libPath = searchFor("eclipse", lib.getAbsolutePath()); //$NON-NLS-1$ } else if (lib.exists()) { libPath = lib.getAbsolutePath(); } } if (libPath == null) { /** * 根据OS、WS、Arch等信息,加载相应的本地文件(如,dll或so)。 */ //find our fragment name String fragmentOS = getOS(); String fragmentWS = getWS(); String fragmentArch = getArch(); libPath = getLibraryPath(getFragmentString(fragmentOS, fragmentWS, fragmentArch), defaultPath); if (libPath == null && ws == null) { // no ws was specified and we didn't find the default fragment, try an alternate ws String alternateWS = getAlternateWS(fragmentWS); libPath = getLibraryPath(getFragmentString(fragmentOS, alternateWS, fragmentArch), defaultPath); if (libPath != null) { System.getProperties().put(PROP_WS, alternateWS); } } } library = libPath; if (library != null) bridge = new JNIBridge(library);//并创建JNIBridge,这个还有待研究 }
invokeFramework()启动Equinox框架
private void invokeFramework(String[] passThruArgs, URL[] bootPath) throws Exception { //如果没有指定ClassLoader,默认将boot设置为OSGi框架的ClassLoader的父类 String type = System.getProperty(PROP_FRAMEWORK_PARENT_CLASSLOADER, System.getProperty(PROP_PARENT_CLASSLOADER, PARENT_CLASSLOADER_BOOT)); ClassLoader parent = null; if (PARENT_CLASSLOADER_APP.equalsIgnoreCase(type)) parent = ClassLoader.getSystemClassLoader(); else if (PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) { ClassLoader appCL = ClassLoader.getSystemClassLoader(); if (appCL != null) parent = appCL.getParent(); } else if (PARENT_CLASSLOADER_CURRENT.equalsIgnoreCase(type)) parent = this.getClass().getClassLoader(); //生成一个Equinox框架的StartupClassLoader,(关于ClassLoader分层机制,还有待研究) URLClassLoader loader = new StartupClassLoader(bootPath, parent); //通过该ClassLoader加载org.eclipse.core.runtime.adaptor.EclipseStarter类,并调用其run方法 Class clazz = loader.loadClass(STARTER); Method method = clazz.getDeclaredMethod("run", new Class[] {String[].class, Runnable.class}); try { //将命令行参数及闪屏线程对象传递给run方法 method.invoke(clazz, new Object[] {passThruArgs, splashHandler}); } catch (InvocationTargetException e) { } }
接下来看一下EclipseStarter.run()
public static Object run(String[] args, Runnable endSplashHandler) throws Exception { if (Profile.PROFILE && Profile.STARTUP) Profile.logEnter("EclipseStarter.run()", null); //$NON-NLS-1$ ... ... try { startup(args, endSplashHandler); ... ... Object obj=run(null); return obj; } catch (Throwable e) { ... ... } finally {... ...} return null; }
public static BundleContext startup(String[] args, Runnable endSplashHandler) throws Exception { ... ... FrameworkProperties.initializeProperties(); processCommandLine(args); LocationManager.initializeLocations(); loadConfigurationInfo(); finalizeProperties(); if (Profile.PROFILE) Profile.initProps(); // catch any Profile properties set in eclipse.properties... adaptor = createAdaptor();//建立适配器 framework = new Framework(adaptor);//创建Equinox框架 context = framework.getBundle(0).getBundleContext(); registerFrameworkShutdownHandlers(); publishSplashScreen(endSplashHandler);// consoleMgr = ConsoleManager.startConsole(framework);//控制台启动,会有信息输出 framework.launch();//启动框架 Bundle[] startBundles = loadBasicBundles();//loading basic bundles ... ... // set the framework start level to the ultimate value. This will actually start things // running if they are persistently active. setStartLevel(getStartLevel());//StartLevel set // they should all be active by this time ensureBundlesActive(startBundles); return context; }
先到这里,有空继续分析
/** * Runs the application for which the platform was started. The platform * must be running. * <p> * The given argument is passed to the application being run. If it is <code>null</code> * then the command line arguments used in starting the platform, and not consumed * by the platform code, are passed to the application as a <code>String[]</code>. * </p> * @param argument the argument passed to the application. May be <code>null</code> * @return the result of running the application * @throws Exception if anything goes wrong */ public static Object run(Object argument) throws Exception { if (Profile.PROFILE && Profile.STARTUP) Profile.logEnter("EclipseStarter.run(Object)()", null); //$NON-NLS-1$ if (!running) throw new IllegalStateException(EclipseAdaptorMsg.ECLIPSE_STARTUP_NOT_RUNNING); // if we are just initializing, do not run the application just return. if (initialize) return new Integer(0); try { if (appLauncher == null) { boolean launchDefault = Boolean.valueOf(FrameworkProperties.getProperty(PROP_APPLICATION_LAUNCHDEFAULT, "true")).booleanValue(); //$NON-NLS-1$ // create the ApplicationLauncher and register it as a service appLauncher = new EclipseAppLauncher(context, Boolean.valueOf(FrameworkProperties.getProperty(PROP_ALLOW_APPRELAUNCH)).booleanValue(), launchDefault, log); appLauncherRegistration = context.registerService(ApplicationLauncher.class.getName(), appLauncher, null); // must start the launcher AFTER service restration because this method // blocks and runs the application on the current thread. This method // will return only after the application has stopped. return appLauncher.start(argument); } return appLauncher.reStart(argument); } catch (Exception e) { if (log != null && context != null) // context can be null if OSGi failed to launch (bug 151413) logUnresolvedBundles(context.getBundles()); throw e; } }
发表评论
-
再说SWT中的滚动面板ScrolledComposite实现
2013-06-19 15:43 2257记得以前写过一篇关于滚动面板的文章 SWT中 Scrolle ... -
OSGi参考资料
2013-04-18 01:11 652基于 OSGi 的面向服务的组件编程 探索 OSGi 框架的组 ... -
CDT(编辑、调试)参考资料
2013-04-17 02:15 1074CDT编辑器 --------- 构建基于 CDT 的编辑器, ... -
Workspace Resource框架专题(3)处理工作空间资源更改事件
2013-04-17 01:44 13283 处理工作空间资源更改事件 工作空间API允许工具对它 ... -
Workspace Resource框架专题(2)workspace 框架API
2013-04-17 01:27 14242 工作空间API 本 ... -
Workspace Resource框架专题(1)Resource的概念
2013-04-17 01:12 13381 Resource的概念 如 ... -
如何恢复断点及Marker
2013-03-05 00:41 0如何恢复断点及Marker -
深入Workbench框架
2013-03-01 02:10 1634深入Workbench框架(结合UIPersistent) 1 ... -
Eclipse插件开发中的Action
2013-02-24 23:10 1961插入点用来定义菜单出 ... -
Eclipse开发中编辑器(Editors)和视图(View)总结
2013-02-24 22:58 28231.视图(Views) 视图( ... -
SWT/JFace专题 --- 对话框向导(Dialogs Wizards)
2013-02-24 22:42 2113对话框向导(Dialogs Wizar ... -
SWT/JFace专题 --- JFace
2013-02-24 22:37 1571JFace JFace是基于SWT的一套图形工具包,它没有为 ... -
SWT/JFace专题 --- SWT中Display和多线程
2013-02-24 15:25 3160Display 1.Display 的创建 一个SWT程序 ... -
SWT/JFace专题 --- SWT API 结构
2013-02-23 18:31 1042SWT API 结构 1.布局类(l ... -
SWT/JFace专题 --- SWT结构浅析
2013-02-23 17:02 985SWT技术是一套基于Java的 ... -
Eclipse平台体系结构
2013-02-21 23:56 17751.Eclipse平台体系结构 1 ... -
RCP平台架构
2013-02-23 14:11 1403RCP 富客户端通常是指具有独立用户界面的客户端程序。富客户 ... -
Ant构建脚本相关
2013-02-18 01:26 0Ant构建脚本相关 -
CDT源码架构研究
2013-02-18 01:24 0CDT源码架构研究 -
SWT/JFace专题 --- SWT/JFace概述
2013-02-23 16:59 822SWT(Standerd Widget Toolkit,标准图 ...
相关推荐
Eclipse-OSGi内核源码分析
“基础篇”对Eclipse平台做了简单的介绍,并列举了一些在Web开发过程中经常用到的Eclipse功能;“进阶篇”主要介绍了在Web开发中常用的技术,如Struts、Hibernate、Tomcat、Spring等以及这些技术在Eclipse平台中可能...
Tomcat8源码,依赖添加完毕,可以在eclipse中直接运行,分析tomcat运转流程。 如果报错,拷贝conf和webapps文件夹到output/build目录下即可。
Eclipse开发技术详解书中的源代码,以供学习之用~~
“插件开发篇”介绍了Eclipse插件开发的各个步骤,并给出了一个基于数据库开发和面向对象分析设计的完整插件实例;“Web开发篇”以Tomcat+Lomboz+Hibernate为开发环境,详述了其下载、安装、配置和开发的全过程。 ...
Eclipse AST分析java源码.doc Eclipse AST分析java源码.doc
Activity启动流程源码分析,使用eclipse代码跟踪,图片详解
Eclipse中的将工作台部分分成了视图和编辑两个方面由: IWorkbenchPartFactory的两个方法:createView(String,Composite,IMemento,ServiceFactory)和 createEditor(String,Composite,IMemento,ServiceFactory负责...
基于Eclipse+MySQL设计的餐馆点菜系统软件源码+说明文档资料 1.1. 目的 通过本课程设计的实践及其前后的准备与总结,复习、领会、巩固和运用软件工程课堂上所学的软件开发方法和知识, 全面掌握软件工程管理、软件...
这是一个简单的java计算器的txt源代码,很适适java初学者们分析,可直接粘贴到eclipse,生成.慢慢揣摩!
基于Java Eclipse 设计餐厅点菜系统软件源码+说明文档资料 1.1. 目的 通过本课程设计的实践及其前后的准备与总结,复习、领会、巩固和运用软件工程课堂上所学的软件开发方法和知识,以此来完成点餐系统的分析、设计、...
图片加载框架Fresco源码,Eclipse源码,Android4.4以上,最基础的使用方式
Eclipse开发入门与项目实践 Eclipse开发入门与项目实践 源代码 Eclipse开发入门与项目实践 源代码 Eclipse开发入门与项目实践 源代码 第一部分 开发入门 第1章 Eclipse概述及开发环境搭建 2 1.1 Eclipse概述 2...
(1)BundleBundle 操作,启动、停止更新卸载及 操作,启动、停止更新卸载及 BundleBundle 状态。 (2)BundleBundle 信息,头、 信息,头、 ID 、LocationLocation LocationLocation Location 、特征名称和上次更新...
OpenStack Nova源码分析之基础环境配置eclipse+pydev
基于JAVA和Eclipse开发环境的网络爬虫技术网络新闻分析软件程序源码+WORD说明档. 本系统 结构如下: (1)网络爬虫模块。 (2)中文分词模块。 (3)中3文相似度判定模块。 (4)数据结构化存储模块。 (5)数据可视...
org.apache httpclient 4.5源代码,通过eclipse代码项目代码后可以直接查看httpclient源代码,与您的工程代码关连起来。