First, some background.
Since Eclipse Ganymede (3.4) p2 has been the provisioning platform of choice for Eclipse and Eclipse-based applications. p2 introduced many features such as own repository concept, artifact mirroring, general purpose provisioning, revert functionality and much more. Even though p2 has been used primarily for Eclipse provisioning and extending, the system has the potential to fit in many environments and scenarios. There is a p2.core feature that is decoupled from Eclipse and although it contains a fairly big number of bundles, I hope these will be reduced in future as some of them aren’t crucial for normal operations.
Basically all that is required is an Equinox based environment, although work is going on to support Felix too in future.
But what are p2 repositories?
As Eclipse adopted p2, more and more repositories started to emerge.
AFAIK there isn’t a central p2 repository for all Eclipse artifacts. The largest repository I’ve seen is the Eclipse features update site. To understand what a p2 repository looks like, take a look at an example produced by jetty-wtp build.
In a nutshell a p2 repository combines a metadata repository, used for resolution and an artifact repository, used for finding and collecting artifacts.
The most important characteristic of p2 repositories, and a substantial difference compared to Ivy and Maven repositories, is the separation of concerns – artifacts are decoupled from their metadata.
Ivy and Maven have a fixed notion of dependencies between artifacts at a single level of granularity (dependency on a whole artifact).
In theory p2 abstracts dependencies and use them for resolution – a dependency is identified by namespace + name + version, for instance:
- namespace=’java.package’ name=’javax.naming’ version=’1.0.0′
- namespace=’osgi.bundle’ name=’org.apache.log4j’ version=’1.5.0′
In practice this means we can depend not only on artifacts but on packages as well. That kind of flexibility and freedom of specifying the desired granularity level allows you to provision a target system containing only components you really need to use.
All in all the main difference between the technologies is their purpose. Ivy and Maven are build-time technologies that build and publish artifacts while p2 is used for provisioning which includes publishing, resolving, and installing already built artifacts either to a fresh system or alongside existing artifacts.
p2’s metadata repository contains installable units that represent the artifacts. An installable unit(IU) contains the minimal information required for resolution and installation. An IU is also the minimal unit of a provisioning operation. A metadata repository may also contain features which are used to group installable units.
Below is a sample unit from the p2 metadata repository for Gemini Management. The complete metadata is contained within the content.xml file. In this particular example p2’s repository compression feature was used that’s why you’ll find the xml file zipped in the content.jar file.
The artifact repository contains simple declarations of the artifacts contained in the repository. Crucially, mapping rules define how the declared artifacts map to the filesystem in relation of the artifacts.xml location.
p2 repositories are easily created with p2 Eclipse tooling or using Maven with tycho‘s p2 publisher plugin. You can put a p2 repository almost anywhere, although it makes sense to put repositories where they can be most easily accessed.
An example of a Maven job is the pom.xml of the Gemini Management p2 repository. (ignore the <profiles> element)
You can find out more about p2 usage and p2 repositories here.
Development and p2
When developing in Eclipse these days people tend to use target platforms and MANIFESTs to manage their component’s dependencies.
In a nutshell a target platform represents the platform you are developing for. A great feature of a target platform is that it allows you to add remote locations along with local bundle locations and because target platforms are integrated with p2 provisioning the remote bundles are provisioned and cached locally.
This allows developers to easily define the target platform they will develop for, build against it and manage it from a central place.
Is there a place for Nexus in all this?
Nexus is a repository manager from Sonatype, the guys who take care of p2 and tycho, so naturally it has great support for both p2 and tycho. The free version of Nexus supports only Maven repositories although a commercial version adds support for
Ivy and p2 repositories.
UPDATE: Jason van Zyl pointed out in the comments that the p2 work Sonatype has done for Nexus is in the process of being open sourced. This means the free version of Nexus will support p2 repositories too!
Nexus has many great features such as aggregating repository indexes and presenting them as one and also repository proxying and hosting features. I read it can also keep up-to-date p2 metadata for a maven repository.
I’m not very experienced with Nexus but it looks like a very convenient way to manage your repositories.
I haven’t heard of an Eclipse dedicated Nexus instance but it certainly looks promising to me and worth trying out.
What about runtime?
Azure Bondi is planned to be released with p2 support. Both initial provisioning and extending the server are among the scenarios that we are aiming to support.
Let’s talk a bit about these two scenarios.
Initial provisioning means it’ll be possible to install Virgo from a p2 repository on a local machine. Being integrated with p2 this will then enable a user to extend a Virgo instance with installable units or features from other p2 repositories.
You can use p2 to extend Virgo either from within or via an external p2 client. If you use the external client, it won’t matter if Virgo is online or offline.
Now let’s look at an example scenario. I’m a developer and I want to develop an app using Gemini JPA, EclipseLink and Gemini Management. Assuming they all have p2 repositories (update sites) I can add them to my target platform and develop my app. When I’m done I can replay the whole process on my Virgo server using either
- an internal p2 client such as p2 support in Virgo’s Web Admin Console, or
- an external p2 client such as the p2 director application in the Eclipse IDE.
I can specify which features or installable units I want to provision, specify the three repositories and execute the provisioning operation, at which point the artifacts are downloaded and installed and I can run and test my app on top, confident that this is the same environment I’ve built the app for.
Having all this in mind it’s clear that a richer user experience relies on how many runtime components are available in p2 repositories. Ideally every Eclipse RT project will have one.
Then I would love to see a repository, such as Eclipse’s update site, contain Virgo and Eclipse RT components. With such a repository users will be able to provision any components on their Virgo instance (or every other OSGi environment) and update those components or even the whole server in a single shot. Another benefit is transparent application dependency management since provisioning an application in this way will also provision its dependencies from the repository.
Hopefully you are now familiar with many of p2’s features such as initial provisioning of any software, extending OSGi frameworks and publishing p2 repositories. You will also appreciate the potential benefits of a p2 ecosystem in Virgo and Eclipse RT environments. Integrating p2 support into Virgo will open up all sorts of interesting possibilities and, most importantly, will ultimately make developers’ lives easier.