First, consider using Declarative Services (DS) instead of ServiceTracker. While ServiceTracker is higher level than the plain service APIs in the OSGi framework, DS is a much nicer and higher level model for providing and consuming services. It also now supports field injection, so your service dependencies can be injected into your annotated fields. See http://www.slideshare.net/bjhargrave/field-injection-type-safe-configuration-and-more-new-goodies-in-declarative-services for the new DS features.
@Component(immediate=true)
public class MyComponentImpl {
@Reference
private LogService myLogService;
@Activate
private void startThreads() {
// Start the thread(s) that refer to (use) myLogService
}
@Deactivate
private void stopThreads() {
// Interrupt and join the thread(s) that refer to (use) myLogService
}
}With that said:
I am not sure I see the value in putting object in your own field. You miss the default behavior of getService() returning the highest ranked service when there can be multiple services. Also the tracker implementation properly caches this result for quick return.
The tense of the customizer method name tells you when it is called relative to when the tracking event occurred. addingService is "ing" so it is in the process of being tracked and is thus before the service becomes tracked. removedService is "ed" so it is past tense and thus after the service is no longer tracked but it is called during the service's unregistration so the service being untracked is still valid at the time of the removedService call.
--
BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
hargr...@us.ibm.com
BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
hargr...@us.ibm.com
----- Original message -----
From: Michael Lipp <m...@mnl.de>
Sent by: osgi-dev-boun...@mail.osgi.org
To: osgi-dev@mail.osgi.org
Cc:
Subject: [osgi-dev] Clarify usage of ServiceTracker
Date: Wed, Apr 13, 2016 4:47 PM
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
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev