Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 358864 - Injection of Declarative Service Fails in Command Handler
Summary: Injection of Declarative Service Fails in Command Handler
Status: CLOSED INVALID
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 4.1   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-26 06:28 EDT by Markus Stier CLA
Modified: 2011-09-26 10:53 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Stier CLA 2011-09-26 06:28:24 EDT
Build Identifier: I20110620-1631

I'm currently implementing an e4 application based on eclipse 4.1. I've created an OSGI bundle (session bundle) which provides an declarative service "ISessionService". It is declared with immediate="true" and the start level of the bundle is below the start level of the application bundle. 

I want to have eclipse inject an instance of my ISessionService into my LoginHandler, which is declared as a command handler in the application defining XMI. During startup the following exception is thrown:

org.eclipse.e4.core.di.InjectionException: Unable to process "LoginHandler.m_ss": no actual value was found for the argument "ISessionService".

The LoginHandler class:

public class LoginHandler {

	@Inject 
	ISessionService m_ss; 

	@Execute
	public void execute(IEclipseContext context) {
            m_ss.dosomething();
            // details omitted...
	}
}

If I create an instance of the service in the bundle activator of the session bundle, anything works fine. 

BundleActivator:

 @Override
    public void start(BundleContext bundleContext) throws Exception
    {
        s_Context = bundleContext;

        ISessionService sservice = new SessionService();
        s_Context.registerService(ISessionService.class.getName(), sservice, null);

    }

In my understanding of e4 injection this shouldn't be necessary, isn't it?

Best Markus


Reproducible: Always
Comment 1 Remy Suen CLA 2011-09-26 07:47:09 EDT
Oleg, any ideas?
Comment 2 Simon Chemouil CLA 2011-09-26 08:07:12 EDT
It doesn't look like a problem with E4 since it works when you programmatically register your service. A more interesting example would be programmatically retrieving your service (with context.getServiceReference(ISessionService.class)) to see if it's properly registered.

Markus, if you enable Equinox' console (-console as a launching option), is your component listed and satisfied if you type "ls" (list components)?
Comment 3 Markus Stier CLA 2011-09-26 10:35:31 EDT
(In reply to comment #2)
> It doesn't look like a problem with E4 since it works when you programmatically
> register your service. A more interesting example would be programmatically
> retrieving your service (with
> context.getServiceReference(ISessionService.class)) to see if it's properly
> registered.
> 
> Markus, if you enable Equinox' console (-console as a launching option), is
> your component listed and satisfied if you type "ls" (list components)?

Sorry my fault!

It turns out, that the SessionServiceImpl, which implements ISessionService, had a dependency to another service, which wasn't available at application startup. I removed the dependency and the service gets injected as expected. 
Sorry again. I did not realize that the instantiation of services is deferred until all dependencies are resolved.
Comment 4 Simon Chemouil CLA 2011-09-26 10:53:41 EDT
(In reply to comment #3)
> It turns out, that the SessionServiceImpl, which implements ISessionService,
> had a dependency to another service, which wasn't available at application
> startup. I removed the dependency and the service gets injected as expected. 
> Sorry again. I did not realize that the instantiation of services is deferred
> until all dependencies are resolved.

Yes, DS will behave this way if a reference is set as mandatory (1..1 or 1..n) and static. If you want another behavior, you can set it to optional and/or dynamic. Be careful that setting it static and optional (0..1) will mean that if it's not satisfied at the time the component is activated, it will never be satisfied.

Closing this issue.