I have written an OSGi bundle to use it in my eclipse 4 rcp application. The usage of the service works fine if I add the dependencies, register these service in my activator and inject it in my class.
In activator
IUserService service = new TestUserService();
context.registerService(IUserService.class.getName(), service, null);
In my class
@Inject
IUserService service;
service.getSth();
I read that using bundles via declarative services should be the better way. So changed my implementation. I created a component definition in my bundle to provide my service:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="usermanagement.test">
<implementation class="usermanagement.test.TestUserService"/>
<service>
<provide interface="usermanagement.IUserService"/>
</service>
</scr:component>
Then I removed the service registration from my activator and created an service consumer class:
public class UserServiceConsumer {
private IUserService service;
public synchronized void setQuote(IUserService service) {
this.service = service;
}
public synchronized void unsetQuote(IUserService service) {
if (this.service == service) {
this.service = null;
}
}
}
and another component definition:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="UserServiceConsumer">
<implementation class="services.UserServiceConsumer"/>
<reference bind="setService" cardinality="1..1" interface="usermanagement.IUserService" name="IUserService" policy="static" unbind="unsetService"/>
</scr:component>
After these modifications the injection of my serivce does not work anymore. The problem is that the injected service reference is NULL everytime.
Does anyone know why? Did I forgot something?
Thanks a lot!
I can suggest a few things you can do to debug.
Have you actually got an scr implementation in your runtime? SCR (another name for declarative services) isn't included in Equinox core, so you'll need to include it. Most people use the Felix SCR bundle - it will sit very happily on top of Equinox.
Since Declarative Services just use services, you can change one half of your app at a time, to identify whether it's the service consumption or registration which isn't working.
You can also use the Equinox console to inspect your service registration. Use 'ss' to identify your bundle, then 'bundle [no]' to see what services are registered and consumed. If you're using Felix SCR, there are also Equinox console extensions, so you can use 'scr list' to see all services which a bundle attempts to register (and their state), and 'scr info' for more details on a particular service.
I have found a solution.
In the manifest file of my service I have added the following line:
Bundle-ActivationPolicy: lazy
After that the userServiceConsumer and component definition in my application are unneeded.
In a view class I can do the following now:
public class MyPart {
private IUserService uServ;
@Inject
public MyPart(IUserService uServ) {
this.uServ = uServ;
if (uServ != null)
System.out.println("UserService available");
else
System.out.println("UserService == null");
}
Via DI my service is injected in constructor of the view. That works for me!
I think declarative services will not work in your UI class as it will not be created by the SCR but by Eclipse.
So what you can try is to leave the UI as it was with @Inject
and only change the bundle providing the service to use DS.
Basically I would not even try to change the UI side. The @Inject
notations is much less overhead than the declarative services.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With