A little bit more...

Showing posts with label plugin. Show all posts
Showing posts with label plugin. Show all posts

Friday, April 20, 2007

The Architecture of Eclipse

Introduction

If explaining every bit in detail, you must be missed in the details and can’t see the architecture from a global perspective, nor will you be benifited in your practise. So I’m trying to explain the architecture based on senarios such as what will happen when you startup elipse, what will happen when an action that you contribute is fired, etc. I hope in such a way it will do help in your practice with Eclipse.

And, it is worthy to point out this is not an overview on the architecture of Eclipse for which there are tons of articles written about.

Startup of Eclipse

What will happen when the file eclipse.exe is executed.

Startup of Eclilpse begins by running a system specific executable binary file called eclilpse.exe which is located under the root directory of the eclipse installation. This executable will then lauches the org.eclipse.core.launcher.Main, located in startup.jar. After that the entry point of Main, that is static main method of Main is invoked. Below we will illustrate the calling path of important methods to demonstrate the post startup process of Eclipse.

Main.run( args )

Main.basicRun( args )

Main.getBootPath( .. ) : locate boot plugin ( in “plugin” directory of your eclispe installation ), within which Main.getDevPath( .. ) is called, within which Main.addBaseJars( .. ) is called, within which Main.readFrameworkExtensions( .. ) is called; invokeFramework( .. ): invoke EclipseStarter

the class EclipseStarter ( indicated by STARTER field ) is loaded by a URLClassLoader defined as an inner class with Main; EclipseStarter.run( .. ) is invoked in a reflective way

EclipseStarter.startup( .. ) : starts the platform and sets it up to run a single application

OSGi.new( .. ) : an instance of OSGi service platform is created

OSGi.launch() : start the OSGi framework

Framework.launch()

SystemBundle.resume() : SystemBundle subclasses Bundle to provide a system Bundle so that the framework can be represented as bundle

StartLevelManager.launch( .. ) : StartLevelManager is the startLevel service implementation for the OSGi spec

StartLevelManager.doSetStartLevel( .. )

StartLevelManager.incFWSL( .. )

StartLevelManager.getInstalledBundles( .. ) : Build an array of all installed bundles to be launch; StartLevelManager.loadInstalledBundles( .. ) : Load all bundles; StartLevelManager.resumeBundles( .. )

Framework.systemBundle.context.start() : Framework. :SystemBundle. :BundleContextImpl.start(), start the system bundle, BundleContextImpl.start() calls bundle’s BundleActivator.start()

BundleHost.loadBundleActivator() : Load and instantiate bundle’s BundleActivator class

BundleContextImpl.startActivator( .. ) : calls the start method of a BundleActivator which you have to extend when you create a plug-in.

Eclispe can also be started from with a client ( which is not part of the current Eclipse platform ), say, written in java, by using the EclispeStarter class located in org.eclipse.core.runtime.adaptor.

Action delegate and proxy

What will happen when your contributed action is fired.

Adding an action in a programatic way is different from adding it via contribution to an action extension point. For the former case, you have to implement some special API to create an action directly, while for the latter case you will have to only implement IActionDelegate+ which enables the lazy loading of the action.

At startup the registry is read and a PluginAction( extends Action, implements *Selection*Listener, IPluginContribution ) is created for each action extension point. The instance of PluginAction is an action proxy which directly represent an action in run time but doesn’t do the job a real action does. When the action that the action proxy represents is fired, the real action( the action delegate ) is created by the action proxy. After that point the action proxy delegate everything that is requested to the real action, the action delegate. This mechanism makes it possible to load the action extension lazily which is called lazy loading.

Following depicts the flow of action proxy and delegate:

read from registry ( IExtensionRegistry ) -> a PluginAction created for each action extension point ( while the action is fired -> an action delegate created -> action is delegated )

Contribute an Extension

to be continued…

Extension Pattern

Adapter pattern is extensively used in Eclipse to contribute extensions ( different from extensions to extension point ) to type or instance. This mechanism is enabled mainly by implementing IAdaptable and IAdapterFactory. For the detailed explanation with examples, please refer to Chapter 31 of the book Contributing to Eclipse: Principles, Patterns, and Plugins (Paperback).

Resources

  1. The Architecture of Eclipse. This article refers to and linked to a lot of valuable resources.
  2. A First Look at Eclipse Plug-In Programming. Contains a very detailed comparsion between Sun’s awt and swing and Eclipse’s SWT and JFace and anatomy of the process of Eclispe startup.
  3. About the OSGi Service Platform - Technical Whitepaper Revision 4.0
  4. org.eclipse.osgi_3.2.2.R32X_v20070118.jar : org.eclipse.core.runtime.adaptor.EclipseStarter.class source code, org.eclipse.osgi.framework.internal.core.AbstractBundle.class source code, org.eclipse.osgi.framework.internal.core.BundleContextImpl.class source code, org.eclipse.osgi.framework.internal.core.BundleHost.class source code, org.eclipse.osgi.framework.internal.core.Framework.class source code, org.eclipse.osgi.framework.internal.core.OSGi.class source code, org.eclipse.osgi.framework.internal.core.StartLevelManager.class source code, org.eclipse.osgi.framework.internal.core.SystemBundle.class source code, org.osgi.framework.BundleActivator.class source code.
  5. org.eclipse.ui.workbench_3.2.2.M20070119-0800.jar source code.
  6. eclipse 3.2.2 startup.jar : org.eclilpse.core.launcher.Main.class source code.
  7. Contributing to Eclipse: Principles, Patterns, and Plugins (Paperback)
  8. Eclipse Help

to be continued…

Technorati : , , , , , ,
Del.icio.us : , , , , , ,

Wednesday, March 21, 2007

newClasspathContainerEntry

Introduction

Setting Java project build path involves setting classpaths of the project which are different from the Java runtime classpath. In JDT classpaths are represented with classpath entries which roughly fall into five kinds: source folder entries, binary library entries, prerequisite project entries, classpath variables, and classpath containers.

Start you eclipse JDT, open a Java project and launch the build path configuration window, and you’ll find all the options enabling you to add/remove all kinds of classpath entries. The frequently used JAVA_HOME system variable (under Windows) can be considered as a classpath variable here. And for a classpath container, hereafter comes more.

Classpath Container

Conceptually it is a data structure which represents a set of tupes with each in the form of . An instance of this data structure can be referenced as an instance of IClasspathEntry which wrapped a unique path of type IPath called a container path. It is noteworthy that all kinds of classpath entries mentioned above are represented by instances of IClasspathEntry within which there is a field called kind identifying the kind of entries. And also, it is noteworthy that an instance of ClasspathContainer is not an instance of IClasspathEntry of kind container. Simply speaking, each instance of IClasspathEntry of kind container references as its member field a container path which uniquely identifies an instance of the data structure mentioned above which contains (or references) a set of instances of ClasspathContainer. Actually, it’s still a little complicated. But that’s it. Below is sketched the relationship.

IClasspathEntry(kind: container)-aContainerPath –> , …}>.

Ways of Creating Classpath Container Entries

The implementation details are more complicated. Class or interfaces involved in include JavaModelManager, JavaCore, IClasspathEntry, ClassContainer, IClassContainerInitializer, and other Java Model classes. The set of tupes of the form of are maintained in JavaModelManager.

Generally, there’re two ways of creating a classpath container entry. The 1st way is to hard code creating instances of ClasspathContainer, and the 2nd way is to create instances of ClasspathContainer via the lazily invoked classpath container initializer which you may define onto the extension point org.eclipse.jdt.core.classpathContainerInitializer.

The hard code way:

// create an instance of IClasspathEntry of kind CPE_CONTAINER
// but ClasspathContainer associated to this entry are not yet defined.
JavaCore.newContainerEntry(..);

// Create and set the classpath container
JavaCore.setClasspathContainer(..);

// Put container path, containers and projects into hashmaps.
// Invoked in JavaCore.setClasspathContainer(..).
JavaModelManager.containerPut(..)

The initializer way:

// Contribute an extension to the initializer extension point.

When classpath entries contained in containers get resolved, the execution process is:

// Methods resolving classpath entries will get method getClasspathContainer(..) invoked.
JavaCore.getClasspathContainer(..);

JavaModelManager.getClasspathContainer(..);

// Both ways would get this method invoked.
JavaModelManager.containerGet(..);

// The initializer way would get this method invoked,
// within which initializer extension(s) will be lazily invoked.
JavaModelManager.initializeAllContainers(..);
or JavaModelManager.initializeContainer(..);

Resources

  1. Setting the Java build path
  2. JDT 3.2 Source Codes.

Technorati : , , , ,

About Me

My photo
I'm finishing my master degree in Software Engineering, Computer Science. I believe and have been following what Forrest Gump's Mam said: you have to do the best with what god gave you.