Plug-in registry resolution

Last update: April 23, 2003

This document is intended as a home for gathering as much information about the expected semantics for the registry resolution algorithm as possible. The goal is to keep this knowledge separately from the implementation (which may tell a different story), in order to make easier for developers to enhance/fix it or to develop a new algorithm for registry resolution. Comments and improvements are welcome.

Soft pre-requisites

Soft pre-requisites are pre-requisites whose "optional" clause is "true".

Unsatisfied optional pre-requisites should be ignored (handled in the same way as if they didn't exist at all).

An optional pre-requisite will be ignored if any of the following conditions apply:

If an optional pre-requisite is ignored for any of the reasons listed above no error message is generated (but an informational message may be output to indicate that this pre-requisite is being ignored). Ignoring an optional pre-requisite does not cause any plug-ins to be disabled. This causes potential error conditions to be more complex. Each time we have a situation where we have a conflict, we must first check to see if this is an optional pre-requisite.

Version matching

The following applies for both plug-in pre-requisites and fragments matching their associated plug-ins.

Versions have the following form: major.minor.service.qualifier, where major, minor and service are integers and qualifier is a string.

Version Numbers are matched as follows:

Also:

Two or more versions of the same plug-in can only be simultaneously enabled if they all are library plug-ins (they do not expose extension points nor contribute extensions).

If a highest version of a plug-in is disabled for some reason, the new highest version (if available) should replace it (when possible) - all plug-ins (not fragments) that required the disabled version should refer to the new one.

Questions to be answered

  1. What happens if a fragment contributes pre-requisites to a plug-in that has multiple versions, and these pre-requisites cannot be satisfied? Currently, the association of a fragment and a plug-in happens before the resolution itself starts. So if a plug-in a fragment contributes to is disabled, the fragment is lost (we don't try the next highest version). Should we? This would cause all versions compatible with the fragment to be successively disabled, if the fragment contributes unsatisfiable pre-requisites. Do we want that?

Current registry resolution algorithm (RegistryResolver#resolve)

The existing resolution algorithm works based on a directed graph whose nodes represent all versions of a given plug-in, and arc from "a" to "b" means plug-in "a" requires plug-in "b". The algorithm starting point is a set of root vertices (in-degree is 0) - plug-ins that are not required by any other plug-ins. The resolution is done through a depth-first traversal of the graph from the roots to their pre-requisites.

  1. Initial state: Registry initially contains all plug-ins and fragments discovered by the platform - no checking of pre-requisites has been done.
  2. Model objects that are missing mandatory fields are ignored (#required*)
  3. Create a map of plug-in descriptors where for each plug-in id there is a list of plug-in descriptors that have the same id, ordered by plug-in version, higher to lower (#add)
  4. For each fragment in the registry, add it to the list of fragments of the right plug-in descriptor (the highest version that fits the matching criteria) (#linkFragments).
  5. For each plug-in which has a fragment:
  6. Create a set with the identifiers of all root plug-ins in the registry.
  7. If there are no roots, there is circularity - all plug-ins are disabled and the process is finished (registry is emptied if it was to be trimmed).
  8. For each plug-in identifier in the current set of roots:
  9. If the registry is to be trimmed, delete any plug-ins which are not enabled/do not have pre-requisites satisfied (#resolvePluginRegistry).
  10. If the registry is to be linked, link extensions to the targetted extension points (#resolvePluginRegistry).

Problems in the current registry resolution algorithm

  1. all versions of a plug-in are disabled when the version in use causes a conflict - when a plug-in is disabled for causing a conflict, if there are different versions available, the highest one should be selected and the resolution should try to enable that one;
  2. order should not matter - for instance, when a conflict is detected, all plug-ins involved should be disabled not only the one that introduced the conflict (bug 34752);
  3. fragments not associated with a plug-in or fragments not used because another version of the same fragment exists should be trimmed when the user requests it and currently are not (bug 33911).
  4. the resulting plug-in descriptor should indicate which portions came from fragments (feature request 23165).