开发者

OSGi service trackers not always working

开发者 https://www.devze.com 2023-01-05 03:59 出处:网络
Hey guys. We\'re using OSGi services in an Eclipse RCP application. To track them, we\'re using the org.osgi.util.tracker.ServiceTracker class. A sample code from the application looks like

Hey guys. We're using OSGi services in an Eclipse RCP application. To track them, we're using the org.osgi.util.tracker.ServiceTracker class. A sample code from the application looks like

mailServiceTracker = new ServiceTracker(context, MailService.class.getName(), null);
mailServiceTracker.open();
MailService service = (MailService) mailServiceTracker.getService();

Now my problem is that the getService() method frequently returns null when I created a new service. The code works very well for services that are existing for a long time in the application, but each time I create a new service, I have to do many things until the service is finally found and tracked. I regularly try for example

Sometimes those things help, and sometimes they don't. Does anyone have experiences with those trackers and can tell me how to avoid this behavior and how to get the services tracked immediately upon creation?

Thanks


The problem is that the services you want may not have been created yet (especially in an bundle activator, as some bundles may not yet have started). If you still want to use the service tracker, you will need to provide a ServiceTrackerCustomizer, and keep track (sorry, no pun intended) of the services as they come and go.

Or, you could just switch over to Declarative Services that handle this for you.


There is nothing wrong with using ServiceTrackers other than the fact that it's a fairly low-level way of tracking services. Whilst I agree that declarative services are a nice mechanism, simply dismissing ServiceTrackers because of "all sorts of issues" sounds like bad advice.

Back to the question.

As soon as a service tracker is created and opened, it gives you access to all services that match the filter condition you specified upon creation. There is no delay there. The only thing I can think about is that somehow your bundles are not correctly resolved, so services that are registered from a bundle A are simply not visible to a bundle B using a ServiceTracker. To check this, first locate the bundle that exports the package containing the service interface, and then make sure both A and B are actually wired to it.

Explaining the update/refresh mechanism in OSGi a bit more:

Whenever you update something in OSGi, it's a two step process.

Let's assume you update a bundle that contains a new version of an exported package. Let's also assume there is some consumer that imports it. As long as you only update the bundle but not explicitly refresh the wiring (of which import links to which export) the consumer will still be wired to the old version of the package. As soon as you do a package refresh (something you can do in OSGi via the PackageAdmin service) your consumer will be resolved again and will be wired to the new version.

The reason this is decoupled is that you might want to do updates of several bundles and not "refresh" after each one but instead defer such a refresh until all of them are updated.

It's quite possible that this is the effect you're seeing. Initially you only do an update, and only after the refresh will the tracker actually see the new version of the service.


Not being flippant at all, don't use service trackers. They appear to make your life simple, but there are all sort of issues with them. I'd recommend that you look into using Declarative Services instead. The support for DS in Eclipse has been very good from 3.5 onward.

You might want to check out this book and the associated presentations for more information on why using Service Trackers is a bad idea.

http://equinoxosgi.org/

0

精彩评论

暂无评论...
验证码 换一张
取 消