After we've recently tried to introduce Declarative Services on my current project, I've got this question: is it possible to implement declarative services that are also managed services? Specifically, can this be done in a portable, thread-safe manner that also guarantees no dead-locks?
Some of the issues we have come across are: - Some services can't meaningfully register until their configuration is available. Hence they can't declare a service in the DS configuration; they have to perform registration themselves in response to Configuration Admin updated() calls. - Calls from the DS Component Manager (activate and deactivate) and calls from Config Admin (updated) take place in separate threads. Hence synchronisation is necessary. - This is made more difficult by the observation that calls out to the OSGi framework, say to register services or posting events, can deadlock if called from within activate() and deactivate(). So we have to dispatch such operations on separate threads, or carefully limit locking to the right parts of the activate/deactivate/update methods. These problems have proved tricky to solve, making the code in services complex and error-prone. We have now got to the stage where we're considering ditching Declarative Services as a result, but I would like to check if there is some way we can make this work before taking that step. I would be particularly interested to hear from anyone who have successfully implemented declarative services where the services are configured through the Configuration Admin service. There is one approach that I thought may work: The spec seems to suggest that inital configuration for a service should be passed in through the ComponentContext in the activate() method. Then, when the updated() method is called on the service, it can judge whether it should be restarted or not. If it needs to be restarted, it could call disableComponent() directly followed by enableComponent() with itself as argument, to signal to the DS implementation that it should be restarted. This doesn't work with the implementations we have tried so far though... the configuration from Config Admin isn't passed in on activate() and calling disableComponent/enableComponent is executed synchronously, so ends up calling back to deactivate in the service itself. And it's not clear to me if the call to disableComponent/enableComponent is a reasonable way for a declared service to signal that it should be decativated and re-activated. On a related note, I'm starting to wonder if the Declarative Services and/or Config Admin specs are flawed in that these don't really take into account the interaction between the two. It strikes me that configuration updates to a declared service ought to be delivered in a way that is integrated into the Declarative Service lifecycle. But I may be missing something... Your comments and suggestions would be most welcome. Regards, Jan
_______________________________________________ OSGi Developer Mail List [email protected] http://www2.osgi.org/mailman/listinfo/osgi-dev
