Figure A.8 A service consumer may
consume multiple instances of a service.
S ERVICE LIFECYCLES
Services are much more dynamic than you may be accustomed to. They may appear
and disappear at any time. This allows for more interesting applications, but it also
creates some challenges when handling services. Blueprint does a lot of this work for
you, which is why it's preferable to the raw service API s.
If a bundle is stopped, any services it registered are automatically unregistered.
Users of those services need to be able to cope with the possibility of their services
going away. For example, a logging service might be writing to a remote disk that is
disconnected. Instead of the service staying available even though the disk it manages
is gone, the entire service will be unregistered.
What happens to users of a service if the bundle hosting the service is stopped?
The service is unregistered, but instances that have already been created won't magi-
cally vanish. But they'll be stale . The behavior of such services is undefined; they may
continue to work fine, or they may throw exceptions. To avoid being left holding stale
services, the use of ServiceTracker objects to detect when services are unregistered is
a good practice in conventional OSG i. But it adds a lot to the volume of code required
to use services. The enterprise OSG i technologies of Declarative Services and Blue-
print both provide neater handling of the service dynamism.
U SING S ERVICE T RACKERS
Although ServiceReference s are the most obvious way to access services programmat-
ically, the API is pretty low-level and subject to several potential problems. Therefore,
even developers who aren't using Declarative Services or Blueprint tend to prefer a
higher-level API : the ServiceTracker . As the name suggests, ServiceTracker s allow
Search WWH ::