Andres Olarte
Andres Olarte

Reputation: 4380

Using @Inject with OSGi Services with Eclipse4 Dependency Injection

I have 3 plugins

I'm registering QuoteService as an OSGi Service using a Service-Component entry in the manifest, basically following the instructions here.

I'm trying to get this service to be injected in my application, using this code:

package test;

import javax.inject.Inject;

import org.eclipse.e4.core.di.InjectorFactory;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import de.vogella.osgi.quote.IQuoteService;


public class Activator extends AbstractUIPlugin {
    @Inject
    IQuoteService quoteService;

    public static final String PLUGIN_ID = "test"; //$NON-NLS-1$

    private static Activator plugin;


    public Activator() {
    }

    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
        InjectorFactory.getDefault().inject(this, null);
        System.out.println(quoteService.getQuote());
    }

    public void stop(BundleContext context) throws Exception {
        plugin = null;
        super.stop(context);
    }

}

When I run this I get this exception:

Caused by: org.eclipse.e4.core.di.InjectionException: Unable to process "Activator.quoteService": no actual value was found for the argument "IQuoteService".
    at org.eclipse.e4.core.internal.di.InjectorImpl.reportUnresolvedArgument(InjectorImpl.java:412)
    at org.eclipse.e4.core.internal.di.InjectorImpl.resolveRequestorArgs(InjectorImpl.java:403)
    at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:108)
    at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:84)
    at test.Activator.start(Activator.java:45)

I know that my service is registered, because I can access it with this code:

public void start(BundleContext context) throws Exception {
    super.start(context);
    plugin = this;

    ServiceReference serviceReference = context.
              getServiceReference(IQuoteService.class.getName());
    quoteService = (IQuoteService) context.
              getService(serviceReference); 

    //InjectorFactory.getDefault().inject(this, null);
    System.out.println(quoteService.getQuote());
}

Is what I'm trying to do possible? According to some source such as this, it should be possible.

Upvotes: 3

Views: 2301

Answers (1)

greg-449
greg-449

Reputation: 111216

You are not supplying an IEclipseContext to the injection code so it has no way to resolve the service (there is no fallback if you do not supply a context).

In an Activator you can access the OSGi service context with:

IEclipseContext serviceContext = EclipseContextFactory.getServiceContext(bundleContext);

Use ContextInjectionFactory rather than InjectorFactory:

ContextInjectionFactory.inject(this, serviceContext);

Upvotes: 4

Related Questions