雙擊eclipse安裝目錄下的eclipse.exe運行后,會加載同一目錄下的eclipse.ini文件(對應RCP項目也是一樣,在RCP的安裝目錄下會有一個RCPName.ini文件):
- -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參數(shù),,那么則使用這個參數(shù)指定的JRE(jvm.dll庫路徑);
否則,,查看eclipse安裝目錄下是否有JRE文件夾,,如果有的話就使用這個JRE;
否則,,去系統(tǒng)注冊表中查找安裝的JRE,,如果還找不到就報錯。
所以如果不想卸載掉其他的JDK的話,,可以有兩種方式:
直接把要使用的JRE文件夾拷貝到Eclipse目錄下
修改eclipse.ini文件,添加-vm參數(shù),,指定要運行的虛擬機的地址,,形如:
-vm
C:\Program Files\Java\jdk1.6.0_12\bin\..\jre\bin\client\jvm.dll
(在eclipse.ini文件中添加配置項時,有空格就換行,,不然會當成無效參數(shù))
eclipse.ini文件中:
-startup 指定啟動的入口為:安裝目錄下plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
會加載該jar包中的org.eclipse.equinox.launcher.Main.class類并調(diào)用其main(String)完成app的啟動過程
通過一個Exception.printStackTrace()方法來看一下Eclipse的大概啟動過程:
圖中是打印的狀態(tài)棧,,從下往上就是整個Eclipse(或者說RCP程序)的加載和啟動過程,一直到App的啟動,。
下面來通過源代碼,,具體說明:
從org.eclipse.equinox.launcher.Main這個類開始:
在Main這個類的main()方法中下一個斷的,調(diào)試狀態(tài)啟動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);
- ...
- }
主要實現(xiàn)就在basicRun()方法中:
- protected void basicRun(String[] args) throws Exception {
-
- System.getProperties().put("eclipse.startTime", Long.toString(System.currentTimeMillis()));
- commands = args;
-
- String[] passThruArgs = processCommandLine(args);
-
- if (!debug)
-
- debug = System.getProperty(PROP_DEBUG) != null;
- setupVMProperties();
- processConfiguration();
-
- getInstallLocation();
-
-
- URL[] bootPath = getBootPath(bootLocation);
-
- setupJNI(bootPath);
-
-
- if (!checkVersion(System.getProperty("java.version"),
- System.getProperty(PROP_REQUIRED_JAVA_VERSION)))
- return;
-
-
- if (!checkConfigurationLocation(configurationLocation))
- return;
-
- setSecurityPolicy(bootPath);
-
- handleSplash(bootPath);
-
- beforeFwkInvocation();
-
- invokeFramework(passThruArgs, bootPath);
- }
下面針對其中的幾個重要方法進行說明:
processConfiguration:處理配置信息
- private void processConfiguration() {
- URL baseConfigurationLocation = null;
- Properties baseConfiguration = null;
-
-
- 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 {
-
- baseConfigurationLocation = new URL(getInstallLocation(), CONFIG_DIR);
- } catch (MalformedURLException e) {
-
- }
-
-
- baseConfiguration = loadConfiguration(baseConfigurationLocation);
- ... ...
- }
-
- Properties configuration = baseConfiguration;
- if (configuration == null || !getConfigurationLocation().equals(baseConfigurationLocation))
- configuration = loadConfiguration(getConfigurationLocation());
-
- mergeProperties(System.getProperties(), configuration, null);
- ... ...
-
config.ini文件內(nèi)容(舉例)
- #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;
- }
-
- 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 {
-
- 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);
- }
-
-
- 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;
-
-
-
-
-
-
- if (library != null) {
- File lib = new File(library);
- if (lib.isDirectory()) {
- libPath = searchFor("eclipse", lib.getAbsolutePath());
- } else if (lib.exists()) {
- libPath = lib.getAbsolutePath();
- }
- }
- if (libPath == null) {
-
-
-
-
- String fragmentOS = getOS();
- String fragmentWS = getWS();
- String fragmentArch = getArch();
-
- libPath = getLibraryPath(getFragmentString(fragmentOS, fragmentWS, fragmentArch), defaultPath);
- if (libPath == null && ws == null) {
-
- 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);
- }
invokeFramework()啟動Equinox框架
- private void invokeFramework(String[] passThruArgs, URL[] bootPath) throws Exception {
-
- 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();
-
-
- URLClassLoader loader = new StartupClassLoader(bootPath, parent);
-
- Class clazz = loader.loadClass(STARTER);
- Method method = clazz.getDeclaredMethod("run", new Class[] {String[].class, Runnable.class});
- try {
-
- 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);
- ... ...
- 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();
-
- adaptor = createAdaptor();
- framework = new Framework(adaptor);
-
- context = framework.getBundle(0).getBundleContext();
- registerFrameworkShutdownHandlers();
- publishSplashScreen(endSplashHandler);
-
- consoleMgr = ConsoleManager.startConsole(framework);
-
- framework.launch();
-
- Bundle[] startBundles = loadBasicBundles();
- ... ...
-
-
- setStartLevel(getStartLevel());
-
-
- ensureBundlesActive(startBundles);
-
- return context;
- }
先到這里,,有空繼續(xù)分析
-
-
-
-
-
-
-
-
-
-
-
-
- public static Object run(Object argument) throws Exception {
- if (Profile.PROFILE && Profile.STARTUP)
- Profile.logEnter("EclipseStarter.run(Object)()", null);
- if (!running)
- throw new IllegalStateException(EclipseAdaptorMsg.ECLIPSE_STARTUP_NOT_RUNNING);
-
- if (initialize)
- return new Integer(0);
- try {
- if (appLauncher == null) {
- boolean launchDefault = Boolean.valueOf(FrameworkProperties.getProperty(PROP_APPLICATION_LAUNCHDEFAULT, "true")).booleanValue();
-
- appLauncher = new EclipseAppLauncher(context, Boolean.valueOf(FrameworkProperties.getProperty(PROP_ALLOW_APPRELAUNCH)).booleanValue(), launchDefault, log);
- appLauncherRegistration = context.registerService(ApplicationLauncher.class.getName(), appLauncher, null);
-
-
-
- return appLauncher.start(argument);
- }
- return appLauncher.reStart(argument);
- } catch (Exception e) {
- if (log != null && context != null)
- logUnresolvedBundles(context.getBundles());
- throw e;
- }
- }