If you need to track a single service and you don't want to use an extender, you can use the following code instead of the ServiceTracker (which is not well suited for a single service instance as you saw):
https://github.com/apache/karaf/blob/master/util/src/main/java/org/apache/karaf/util/tracker/SingleServiceTracker.java Guillaume Nodet 2016-04-13 22:47 GMT+02:00 Michael Lipp <m...@mnl.de>: > Hi, > > I'm trying to get a clear picture of the ServiceTracker. I've looked at > some examples (e.g. http://www.aqute.biz/Snippets/Tracker), but they all > seem rather complicated. I'm especially interested in knowing when I can > assume a service object to exist. > > It is clear to me from the specification that a service object is > available (different from null) when the default implementation of > addingService returns. So to avoid constantly calling > myTracker.getService() (and check for null) whenever I want to invoke a > method of the service object, I can derive my own ServiceTracker by > overriding addingService (using the LogService as an example): > > @Override > public LogService addingService(ServiceReference<LogService> > reference) { > myLogService = super.addingService(reference); > // Start the thread(s) that refer to (use) myLogService > return myLogService; > } > > ... and use myLogService until the service becomes unavailable (invalid). > > It is less clear to me how to know when the service becomes unavailable. > The specification says: > > removedService(ServiceReference,T) - Called whenever a tracked service > is removed from the > ServiceTracker object. > > IMHO "is removed" is a bit unspecific (before/after?). However, I found in > the Apache Felix implementation (which isn't a specification, of course) > that removedService is invoked while handling the UNREGISTERING event: > > UNREGISTERING - A service object is in the process of being > unregistered. This event is synchro- > nously delivered before the service object has completed > unregistering. That is, during the deliv- > ery of this event, the service object is still valid. > > So I should be on the safe side if I also override removedService: > > @Override > public void removedService(ServiceReference<LogService> reference, > LogService service) { > // Interrupt and join the thread(s) that refer to (use) > myLogService > myLogService = null; > super.removedService(reference, service); > } > > Doing it this way, using myLogService in the thread(s) started in > addingService and stopped in in removeService should be safe, right? > > - Michael > > > _______________________________________________ > OSGi Developer Mail List > osgi-dev@mail.osgi.org > https://mail.osgi.org/mailman/listinfo/osgi-dev > -- ----------------------- Guillaume Nodet ------------------------ Red Hat, Open Source Integration Email: gno...@redhat.com Web: http://fusesource.com Blog: http://gnodet.blogspot.com/
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev