> I think you confuse the validity of a service with its life cycle.
> There is -never- a guarantee that a service is valid. Just think of a
> service that is backed by a remote connection, if the cable is cut
> there is no way you can call that service anymore even though it is
> still registered. There are an infinite amount of cases where a
> service can fail before it is unregistered.
I don't know if these terms have special OSGi semantics, but "valid"
means to me that the service is there, i.e. the service object exists
and -- more important -- can be used, i.e. it's legal (with respect to
the service object's life cycle) to invoke its methods. (Of course,
method invocations can fail as e.g. Input/OutputStreams indicate by the
IOExceptions they throw -- special case RemoteException -- or
PreparedStatement.executeUpdate indicates by an SQLException; these
cases have obviously to be handled somehow in my code when I invoke a
service's method).

What irritates me with a lot of OSGi code examples is the check for
"null" when getting the service. Of course, if I cannot be sure that it
"is there" and "can be used" (i.e. if I cannot be sure that it is
"valid") then I have to check (that's the case in the usual OSGi
examples, because they start the "example's service" without considering
the availability of the service(s) they rely on -- just as in your
snippet http://www.aqute.biz/Snippets/Tracker, that I referred to, where
you simply fall back to System.err if the log service is not available).

In general, if my service relies on another service and I want to invoke
one of that service's methods, I don't want to write code that first
checks for and then handles the special case that the service isn't
valid (isn't there or isn't usable with respect to its life cycle). I
simply want my code to run only if the service I rely on is available in
the first place. (Which implies that I *don't* have to check for null
when getting the service.) So, if my own code (the threads providing the
service) runs only between invocations of "addingService" and
"removedService" (tracking the service I rely on, as in my initial
sample code), then (from my understanding) it should be unnecessary to
check whether ServiceTracker.getService() returns null. Between those
calls it *must* return a service object, right? (This is what I wanted
to clarify.)

 - Michael

>
> The life cycle of services is designed so you can properly clean up
> your own data structures when a service disappears. However, there is
> NEVER a guarantee that you can still call the service. 
>
> Kind regards,
>
> Peter Kriens
>
>
>
>> On 15 apr. 2016, at 10:45, Michael Lipp <m...@mnl.de
>> <mailto:m...@mnl.de>> wrote:
>>
>> BJ Hargrave:
>>> 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.
>> The point is that the validity of the service "while being added" or
>> "after having been removed" cannot be derived from the tense. Being
>> notified "after the service has been removed" actually suggests to me
>> that it is no longer there and therefore invalid. So I think it would
>> be nice to have a clear statement about the validity (just like yours
>> above) in the documentation of "addingService" and "removedService".
>> Maybe it's already stated somewhere else, but I failed to find it.
>> Maybe I should be able to derive it as obvious from the context, but
>> I failed with that as well. (The documentation of UNREGISTERING is
>> much clearer in that respect.)
>>
>> Thanks for the quick response and clarification.
>>
>>  - Michael
>>
>>>  
>>> --
>>>
>>> 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
>>
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org <mailto: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

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to