Tag: plugin development

Eclipse p2 Droplets in Rawhide

So p2 Droplets have been in Rawhide for a little while now, and since then we’ve converted most Eclipse plugins to build using the new format. With the exception of some cases that will be done manually, pretty much everything building with the XMvn macros (%mvn_build, %mvn_install) is guaranteed to be a p2 Droplet after a rebuild. We still support the old format (Dropins), and an installation on rawhide can detect both types, but the goal is to switch completely to Droplets.

If you’re unfamiliar with the term, you can think of p2 Droplets as a new way of packaging one or more Eclipse features. It contains the same jars and feature folders as before but with an additional file (fragment.info) containing some extra data.

The main reason for the switch was that Dropins (using the p2 Reconciler) has been deprecated for a while and has made it much more difficult to diagnose issues when it fails. Eclipse’s first launch actually caches a lot of data to make subsequent ones much faster, and the Reconciler can be a large chunk of that time. I have actually run into cases where installing just an extra package can take the first startup from around 10 seconds, to 3 minutes!

Testing was done with the following setup :

  • Fedora Rawhide Virtual Machine
  • ~700 OSGi bundles on the system
  • ~430 of these bundles to be tested through the Dropins and Droplets approaches
for i in {1..5}; do rm -rf $HOME/.eclipse/ ; (echo exit; echo y;) | /usr/bin/time -f "%E" eclipse -noexit -console ; done;

To test under Dropins, we simply took all the bundles packaged as Droplets and removed their ‘fragment.info’ file, along with the ‘p2.fragments’ line in ‘/etc/eclipse.ini’, just to be sure we completely disabled the new logic.

So what were the results ? Under Dropins, the average startup time was 17.63 seconds, and under Droplets, it was 9.44 seconds. The variance was very small, and nearly the same for both cases so there’s strong evidence that Droplets will be saving a lot of time on Eclipse’s first startup. Of course all subsequent launches (where $HOME/.eclipse is kept) would be much faster (~2s).

So one might ask what’s happened with all the work the Reconciler used to do.

  1. Fedora maintainers do a good job of making sure packages are using the latest version of a library even when upstream isn’t. As a result, things like the Reconciler aren’t as necessary in attempting to satisfy dependencies across different versions
  2. A lot of the logic to calculate dependencies and produce a self-sustaining package is done properly at build-time, and rightfully so because that’s where the provides/requires are generated.

We’ve been working on this change, along with the other aspects of simplifying Eclipse plugin packaging for a while now so it’s nice to see some easy wins immediately from adoption.

Making a Selection Programmatically (Modifying Eclipse ExecutionEvent Context)

Have you ever wanted to reuse a command / action but needed to modify certain things (eg. the elements selected) just before the command was activated ? For example, you have an action that can only be performed when a selection is made. One would think to make the selection programmatically, but is it really necessary to go through the UI just to provide some information ? I managed to find a post describing how to go about this, but it’s worth repeating.

All this information is passed when the command is run as an ExecutionEvent . This has a method Object getApplicationContext() which will return an Object that may be cast to an IEvaluationContext . This, in turn has a method void addVariable(String, Object) that can be used to modify the context.

In my case, setting the context to indicate 2 items had been selected was simply a matter of adding the following code :

IEvaluationContext ctx = (IEvaluationContext) event.getApplicationContext()
  new StructuredSelection(new IResource [] {oldFile, newFile}))

Now you can call your action / command and make sure to pass the ExecutionEvent.

ICommandService cmdService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
Command cmd = cmdService.getCommand("my.command.id");
try {
} catch (Exception e) {
  // Error handling

Setting API Baselines in Eclipse

At eclipse.org, when a project graduates from Incubation, it sheds its 0.N release number for a 1.0 release. Along with this comes the need to solidify its API.

When working on larger projects, with many contributors it can be tricky to know at what point an API breakage has occured. A project can have many different sub-projects, each with its own different set of committers. Add to this, the fact that not all API issues are trivial and we have a recipe for problems to creep in.

No one really wants to be the API police, going around to hunt down problems, and luckily there’s a way to avoid this. Committers can monitor changes to the API themselves.

Eclipse has a handy plugin development feature called “API Baselines”, which allows us to define a set of plugins against which we can compare for changes in API.

We’ll need to find plug-ins for our project with the version we wish to compare against. In this case the 1.0 version is located in this p2 repository, which I’ll just copy over to the local system :

$ eclipse -nosplash -verbose -application org.eclipse.equinox.p2.artifact.repository.mirrorApplication -source ${repoPath} -destination file:/home/rgrunber/linuxtools-1.0

We open Eclipse, and go to Window -> Preferences -> Plug-in Development -> API Baselines.

Click “Add A Baseline” and browse for the folder where we stored our plugins. We’ll just need to give a name to the baseline, and click “Finish”.

We can click “Apply” and it’ll ask us to do a full build, so why not.

Now that we’ve got a working baseline, let’s create a separate Problems view just for these kinds of issues.

Bring up the Problems View, right click on upside-down triangle at the top-right of the view, and go to “New Problems View”.

We’ll name the view “API Baseline Problems”. Once it’s created, go to the same location as before, but for this new menu, and click “Configure Contents”.

Create a new configuration and call it “API Warnings/Errors”. The scope will be “On any element”. The severity will be for Errors, Warnings, and Info, and we’ll only check off “API Problems” in Types.

Once we click ok, this view will show us just the API problems on projects when compared with the baseline we’ve set.

Of course a lot of this is configurable and a matter of preference, but in a few simple steps, we now have the ability to monitor the evolution of our project’s API.