What is p2?
p2 is a provisioning platform for Eclipse-based applications. It replaces the older Update Manager as the mechanism for managing an Eclipse installation. Provisioning is the act of finding and installing new functionality, and updating or removing existing functionality; it is distinct from building.
p2 manages artifacts, such as bundles, features, and products; you can think of these as bags of bytes. p2 not only stores these artifacts, it also stores metadata about these artifacts, such as version information, cryptographic signatures, dependencies between artifacts, platform specifics, and special installation requirements.
Every p2 artifact is uniquely identified by an identifier and version number. For example, the Equinox OSGi container from the Indigo release is a bundle whose identifier is org.eclipse.osgi and version 3.7.0.v20110110.
An artifact is made available to p2 by publishing the artifact to a repository, a process that also adds any metadata about the artifact. p2 comes with several publishers that know how to extract metadata for bundles, features, and products. Most Eclipse build systems (e.g., Tycho, Buckminister, PDE/Build) can automatically publish the artifacts during a build. Other publishers could be created using p2's APIs to handle other types of artifacts (e.g., Windows DLLs).
The p2 Director is responsible for installing a set of artifacts. The Director uses the metadata about an artifact, called an installable unit or IU, to determine how the artifact should be installed and to include any dependencies of those artifacts. Thus installing a product requires installing its associated features, which requires installing the specified bundles; installing the product also requires installing the platform-specific executable.
The Director is a wrapper around several lower-level p2 components. A Profile records the IUs installed. An Agent uses the Planner to determine the IUs to be managed, and uses the Engine to actually perform the sequence of installation steps. These installation steps are handled by touchpoints specific to each type of artifact.
See the p2 concepts guide for more details about these different terms.
Why won't p2 replace an updated bundle in a repository?
p2 assumes that two artifacts with the exact same identifier and version are the same artifact. Once an artifact has been published to a repository, it cannot be replaced. This restriction acts both as a performance optimization, to avoid unnecessary downloads, as well as a consistency check. For example, the Equinox OSGi container from the Indigo release is a bundle whose identifier is org.eclipse.osgi and version 3.7.0.v20110110. Any update to an artifact must be published with a new version number.
How can I find the features that include a particular bundle?
$ eclipse -console -noSplash -noExit -vmargs -Declipse.application.launchDefault=false osgi> provaddrepo http://download.eclipse.org/eclipse/updates/3.7-I-builds osgi> provlpquery * "select(parent | parent.properties['org.eclipse.equinox.p2.type.group'] == true && parent.requirements.exists(rc | everything.exists(iu | iu ~= rc && iu.id == 'BUNDLEID')))" true
For wildcards one may use:
osgi> provlpquery * "select(parent | parent.properties['org.eclipse.equinox.p2.type.group'] == true && parent.requirements.exists(rc | everything.exists(iu | iu ~= rc && iu.id ~= /*BUNDLEID*/)))" true
Credit to Paul Webster.
How do I incorporate p2 into my RCP app?
There are three approaches for integrating p2 into your app.
- The first approach, called the "User Interface API", is actually a framework for managing updates, complete with wizards and configurable scheduling. It is the same framework used by Eclipse's update management. Your application provides policies and other configuration values to guide this framework. Note that this API has a dependency on the Eclipse 3.x Platform UI (org.eclipse.ui), and requires the Platform UI compatibility layer for applications using the Eclipse 4 Application Platform.
- The second approach is to use p2's higher-level Operation APIs to drive updates. These APIs provide a thin layer over the Core APIs (described next) to describe updates as an atomic install, uninstall, or update of an artifact. are more intended for headless applications.
- The third and final approach, is to use p2's Core APIs, where you interact with the p2 agent directly. This is the most powerful, but also most complex, of the possible approaches.
See the worked examples for all approaches in the article on "Equinox/p2/Adding Self-Update to an RCP Application", and the example applications.
Please note that we do not recommend that you invoke the p2 director from your application with a shell call (e.g., "app.exe -application org.eclipse.equinox.p2.director …")!
Why aren't my dropins being picked up?
There is a fourth approach for integrating p2 into your app: using dropins. Dropins are not recommended, and has been officially deprecated by the p2 team. See the dropins debugging section for details on debugging dropins-related issues.
Why am I getting errors trying when access p2 services?
p2 relies on the OSGi Declarative Services feature. You must include and start the org.eclipse.equinox.ds bundle.
Why aren't bundles being removed when their associated feature has been removed?
There are two aspects to this problem.
First, you should ensure that features are recorded when installing a feature by specifying the "org.eclipse.update.install.features=true" property, such that the bundles have a recorded dependency against the feature. This property is not the default, so if you are using the p2 director manually it is worth verifying.
Second, you must invoke the p2 garbage collector. By default, p2 only performs a garbage collect at its discretion. Normally this is fine since the actual bundles to be loaded are still known and managed (either in the config.ini file or by the simpleconfigurator).
You can cause a garbage collect in one of 3 ways:
- Configure your product to invoke a GC on startup by adding the following line to your product's plugin_customization.ini (requires the org.eclipse.equinox.p2.ui.sdk.scheduler bundle):
- Run the garbage collector application:
eclipse -application org.eclipse.equinox.p2.garbagecollector.application -profile SDKProfile
- Explicitly invoke the p2 garbage collection from code:
IProfileRegistry profileRegistry = (IProfileRegistry) ServiceHelper.getService(Activator.getContext(), IProfileRegistry.class.getName()); if (profileRegistry == null) throw new RuntimeException("Unable to acquire the profile registry service."); // can also use IProfileRegistry.SELF for the current profile IProfile profile = profileRegistry.getProfile("SDKProfile"); new GarbageCollector().runGC(profile);
Where can I learn more?
- The p2 wiki
- Pascal Rapicault has a number of presentations on various aspects of p2.
- Eclipse articles and tutorials tagged with p2
- Webinars tagged with p2