Thursday, October 29, 2009

P2 Update Manager Not Allowing Update without restart

I am noticing that if my application requires Declarative Services bundle (in my case, I am using org.eclipse.equinox.p2.ds),. And, if my run launch configuration requires ds and the org.eclipse.core.runtime to be started at startup, I am forced to restart after any update to see the effect of the update.

update:
I stumbled on this link: which appears to address my problem. Apparently, if you configure your own start settings, then you must also explicitly setthe following start values for p2 to work properly:
BundleStart LevelAuto-Start
org.eclipse.equinox.simpleconfigurator1true
org.eclipse.equinox.common2true
org.eclipse.update.configurator4 (default)true
org.eclipse.core.runtime4 (default)true
org.eclipse.equinox.ds1true

Wednesday, October 28, 2009

P2 Update Manager Unable to read repository (local file)

If you get this failure during an update:
"an error occurred while collecting items to be installed" "unable to read repository".

Make sure you have this bundle included "org.eclipse.ecf.provider.filetransfer" as well as any associated "required plugins".

Thursday, October 1, 2009

How to use Declarative Services in RCP Applications

Context

OSGi Declarative Services is very attractive, which spares you from writing a lot of boiler plate code for things like registering/unregistering/consuming services.

I wanted to use OSGi's Declarative Services for dependency injection in RCP applications.  For example, I had a view, in which I would like to use a service SimpleService advertised by Declarative services.

Problem

My first naive approach was to create a component.xml, in which the view class consumes SimpleService. Well, it did not work as I liked, because the view did not have SimpleService injected.

What went wrong?

Nothing went wrong. Declarative Services work as advertised, but my approach was way wrong.

To allow Declarative Services (DS) work, you have to ask DS to instantiate an object for you. During this process, DS injects all necessary services in this newly created object.

However, a view object was created by RCP application launcher outside DS.  What I ended up with were a view object created by RCP application launcher, and another lonely view object created by DS with SimpleService injected but not used in my RCP application launcher.

What is a good approach to inject my SimpleService in my view object?

Solution (a solution)

In your RCP Application's Activator, use ServiceTracker to look up SimpleService. In your view, get SimpleService by Activator.getDefault().getSimpleService().

public class Activator extends AbstractUIPlugin {
    public void start(BundleContext context) throws Exception {
        super.start(context);
        this.context = context;
        lookupService(context);
        plugin = this;
    }

    public static Activator getDefault() {
        return plugin;
    }

    private ServiceTracker tracker;
    private ApplicationUserAdmin userAdmin;
    private void initializeServiceLooup(BundleContext context) {       
        if(userAdmin!=null) {
            return;
        }
        tracker = new ServiceTracker(context, SimpleService .class.getName(),null);
        tracker.open();
    }
    public SimpleService getSimpleService() {
        return (SimpleService ) tracker.getService();
    }

   //other omitted here
}