I am not sure what we’re discussing here? For each of your concerns/objections 
Declarative Services provides a very elegant answer, Service Trackers are only 
used in the rarest of cases. 

Your concerns remind me of a programmer that refused to use a compiler and 
insisted on writing his Java byte codes with Vi … :-) There just happens to be 
a much better solution.

Did you try out the OSGi enRoute Quick Start[1] to get a “feel” for DS?

Kind regards,

        Peter Kriens


[1]: http://enroute.osgi.org/qs/050-start.html 
<http://enroute.osgi.org/qs/050-start.html>








> On 15 apr. 2016, at 11:56, Michael Lipp <m...@mnl.de> wrote:
> 
>> 
>> 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 
> <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 <mailto:hargr...@us.ibm.com>
>>>>  
>>>>  
>>>> ----- Original message -----
>>>> From: Michael Lipp  <mailto:m...@mnl.de><m...@mnl.de> <mailto:m...@mnl.de>
>>>> Sent by:  
>>>> <mailto:osgi-dev-boun...@mail.osgi.org>osgi-dev-boun...@mail.osgi.org 
>>>> <mailto:osgi-dev-boun...@mail.osgi.org>
>>>> To:  <mailto:osgi-dev@mail.osgi.org>osgi-dev@mail.osgi.org 
>>>> <mailto: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>http://www.aqute.biz/Snippets/Tracker
>>>>  <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 <mailto:osgi-dev@mail.osgi.org>
>>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>>> <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 
>>>> <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 
>>> <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 
>> <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 
> <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