The mechanics for supporting plug-ins are implemented using the OSGi framework. From this standpoint, a plug-in is the same thing as an OSGi bundle. The bundle and its associated classes specify and implement the process for Java class-loading, prequisite management, and the bundle's life-cycle. For the rest of this discussion, we use the terms plug-in and bundle interchangeably, unless discussing a particular class in the framework.
The Plugin class represents a plug-in that is running in the platform. It is a convenient place to centralize the life-cycle aspects and overall semantics of a plug-in. A plug-in can implement specialized function for the start and stop aspects of its life-cycle. Each life-cycle method includes a reference to a BundleContext which can supply additional information.
The start portion of the life-cycle is worth particular discussion. We've seen already that information about a plug-in can be obtained from the plug-in's manifest file without ever running any of the plug-in's code. Typically, some user action in the workbench causes a chain of events that requires the starting of a plug-in. From an implementation point of view, a plug-in is never started until a class contained the in the plug-in needs to be loaded.
The start method has been a convenient place to implement initialization and registration behavior for a plug-in. However, it is important to realize that your plug-in can be started in many different circumstances. Something as simple as obtaining an icon to decorate an object can cause one of your plug-in's classes to be loaded, thus starting your plug-in. Over-eager initialization can cause your plug-in's code and data to be loaded long before it is necessary. Therefore, it's important to look closely at your plug-in's initialization tasks and consider alternatives to performing initialization at start-up.
Life-cycle management is where the OSGi "bundle" terminology and the platform's "plug-in" terminology meet. When your plug-in is started, it is given a reference to a BundleContext from which it can obtain information related to the plug-in. The BundleContext can also be used to find out about other bundles/plug-ins in the system.
BundleContext.getBundles() can be used to obtain an array of all bundles in the system. Listeners for BundleEvent can be registered so that your plug-in is aware when another bundle has a change in its life-cycle status. See the javadoc for BundleContext and BundleEvent for more information.
Prior to 3.0, a plugin registry (IPluginRegistry) was provided to supply similar information. For example, it could be queried for the plug-in descriptors of all plug-ins in the system. This registry is now deprecated and BundleContext should be used for this purpose. The platform registry is now used exclusively for information about extensions and extension points.
The BundleActivator interface defines the start and stop behavior implemented in Plugin. Although the Plugin class is a convenient place to implement this function, a plug-in developer has complete freedom to implement the interface for BundleActivator in any class appropriate for the plug-in's design. In fact, your plug-in need not implement this interface at all if it does not have specific life-cycle management needs.
Underneath every plug-in lies an OSGi bundle managed by the framework. The Bundle is the OSGi unit of modularity. Fundamentally, a bundle is just a collection of files (resources and code) installed in the platform. Each bundle has its own Java class loader, and includes protocol for starting, stopping, and uninstalling itself. From the Eclipse platform point of view, Bundle is merely an implementation class. Plug-in developers do not extend the bundle class, but use Plugin or other BundleActivator implementations to represent the plug-in.