- FAQ 94: What is a plug-in?
- FAQ 95: Do I use plugin or plug-in?
- FAQ 96: What is the plug-in manifest file (plugin.xml)?
- FAQ 97: How do I make my plug-in connect to other plug-ins?
- FAQ 98: What are extensions and extension points?
- FAQ 99: What is an extension point schema?
- FAQ 100: How do I find out more about a certain extension point?
- FAQ 101: When does a plug-in get started?
- FAQ 102: Where do plug-ins store their state?
- FAQ 103: How do I find out the install location of a plug-in?
- FAQ 104: What is the classpath of a plug-in?
- FAQ 105: How do I add a library to the classpath of a plug-in?
- FAQ 106: How can I share a JAR among various plug-ins?
- FAQ 107: How do I use the context class loader in Eclipse?
- FAQ 108: Why doesnt Eclipse play well with Xerces?
- FAQ 109: What is a plug-in fragment?
- FAQ 110: Can fragments be used to patch a plug-in?
- FAQ 111: What is a configuration?
- FAQ 112: How do I find out whether the Eclipse Platform is running?
- FAQ 113: Where does System.out and System.err output go?
- FAQ 114: How do I locate the owner plug-in from a given class?
- FAQ 115: How does OSGi and the new runtime affect me?
- FAQ 116: What is a dynamic plug-in?
- FAQ 117: How do I make my plug-in dynamic enabled?
- FAQ 118: How do I make my plug-in dynamic aware?
FAQ 118: How do I make my plug-in dynamic aware?
Dynamic awareness requires extra steps that were not required prior to the introduction of dynamic plug-ins. Dynamic awareness requires that you remove all references to classes defined in other plug-ins when those plug-ins are removed from the system. In particular, if your plug-in defines extension points that load classes from other plug-ins—executable extensions—you need to discard those references when other plug-ins are dynamically removed. The extension registry allows you to add a listener that notifies you when extensions are being added or removed from the system. If your plug-in maintains its own cache of extensions that are installed on your extension point, your listener should update this cache for each added or removed extension.
The following is an example of a simple class that maintains its own cache of the set of extensions installed for a given extension point. This example is a bit contrived as simply caching the extension objects has no value. Typically, your plug-in will process the extensions to extract useful information and possibly load one or more classes associated with that extension. The basic structure of this cache example is as follows:
public class ExtCache implements IRegistryChangeListener { private static final String PID = "my.plugin"; private static final String PT_ID = PID + "." + "extension.point"; private final HashSet extensions = new HashSet(); ... }
The extensions field stores the set of installed extensions for a particular extension point.
The cache has a startup method that loads the initial set of extensions and then adds an extension registry listener in order to be notified of future changes:
public void startup() { IExtensionRegistry reg = Platform.getExtensionRegistry(); IExtensionPoint pt = reg.getExtensionPoint(PT_ID); IExtension[] ext = pt.getExtensions(); for (int i = 0; i < ext.length; i++) extensions.add(ext[i]); reg.addRegistryChangeListener(this); }
The class implements the IRegistryChangeListener interface, which has a single method that is called whenever the registry changes:
public void registryChanged(IRegistryChangeEvent event) { IExtensionDelta[] deltas = event.getExtensionDeltas(PID, PT_ID); for (int i = 0; i < deltas.length; i++) { if (deltas[i].getKind() == IExtensionDelta.ADDED) extensions.add(deltas[i].getExtension()); else extensions.remove(deltas[i].getExtension()); } }
This class is now dynamic aware but is not yet dynamic enabled; that is, the class does not yet support itself being dynamically removed. The final step is to implement a shutdown method that clears all values from the cache and removes the listener from the extension registry:
public void shutdown() { extensions.clear(); IExtensionRegistry reg = Platform.getExtensionRegistry(); reg.removeRegistryChangeListener(this); }
This shutdown method must be called from the shutdown method of the plug-in that defines the cache. For the complete source code of this example, see the ExtCache class in the FAQ Examples plug-in.
Note that not only extensions points acquire and maintain references to classes defined in other plug-ins. You need to be especially aware of static fields and caches that contain references to objects whose class is defined in other plug-ins.
If you hold onto classes defined in other plug-ins through different mechanisms, you also need to discard those references when those other plug-ins are removed.
Note
FAQ 116 What is a dynamic plug-in?
FAQ 117 How do I make my plug-in dynamic enabled?