It has been mention a few times that the AbstractServiceTracker limits user applications in that inheritance imposes a specific structure. I’m interested if anyone has some specific ideas on how a non-inheritance style ServiceTracker could work and still provide the functionality of the existing class. Ideas?
I’m not sure if everyone understands what is meant by "the AbstractServiceTracker limits user applications." So I’ll try to add some detail to this and write down some of my thoughts on the subject to trigger some more interest in this post.
The AbstractServiceTracker was created because we found ourselves writing the same piece of code for different BUG applications. If you are writing a BUG/OSGi application, chances are that the application is dependent on the availability of several OSGi services. The service dependencies define whether the application should run or not. For example, if I write an application that requires the IPositionProvider and the ICameraDevice services, my application should only run when these services become/are available. Otherwise, the application should not run at all.
The current implementation of AbstractServiceTracker is mixing a few "concerns" of the overall application: tracking services and performing some work (the purpose of the application). This mixture leads clients of AbstractServiceTracker to implement Application logic in the doStart() and doStop() abstract methods of their derived classes. By forcing them to inherit from AbstractServiceTracker we are depriving/limiting their applications from extending other classes.
One possible solution to this problem is to take the approach of FlickrUppr. Where the service tracker (FlickrUpprServiceTracker) is used to track services and start FlickrUpprApp when all service dependencies have been met and stop it when they are not met. This approach delegates the application work to FlickrUpprApp and the service tracking work to FlickrUpprServiceTracker.
An application that follows this structure frees the application class from any "limitation" imposed by the AbstractServiceTracker while simultaneously taking advantage of the common functionality it provides.
Going forward, we could create an application interface and a ApplicationServiceTracker to formalize the object composition.
A concise and clear explanation of object composition can be found here:
I'm definitely a fan of composition over inheritance. We talked about this a bit at http://bugbeta.com/forums/viewtopic.php?p=309. I like your suggestion to formalize this. Applications aren't forced to use these convenience mechanisms, so formalizing them won't restrict anything; it will just make it convenient for the majority of straightforward applications.
I can imagine some applications might have a set of mandatory modules that they need to function, but also have some optional modules: an app that can function headless but could report its status on the LCD if/when it was plugged in for example. I assume the application class(es) could register for module notifications as well: the app could use the service tracker for the mandatory modules and register in the app-specific class(es) for notifications of optional ones.
Just my 2 cents...