One way to do this is by using a delegating service proxy. A delegating service proxy is
a thin wrapper that implements the same set of interfaces as the original service. It
contains a single reference to the real service implementation that can be set and
cleared by methods only visible to your registering bundle. By registering this delegat-
ing proxy with the service registry instead of the real service implementation, you stay
in control. Because client bundles are unaware of the internal indirection, they can't
accidentally keep a reference to the underlying service. As figure 8.17 shows, you can
decide to sever the link at any time.
Notice that there's still a small leak, because the rogue client maintains a strong
reference to the service proxy. But this should be much smaller than the graph of
objects and classes referenced by the actual service implementation; otherwise, you
don't gain much by using a proxy.
You can see an example of a service proxy in the code examples:
$ cd chapter08/dangling-services
$ ant dist
$ java -jar launcher.jar bundles
<3> thread="main", bundle=2 : logging ON
The log client is taken from the broken_lookup_field service example from chapter 4.
It caches the log service instance in a field and repeatedly calls it every few seconds:
<3> thread="LogService Tester", bundle=2 : ping
Tr y s t o p p i n g t h e l o g s er v i c e b y g o i n g t o t h e OSG i console and typing
-> stop 1
<3> thread="Thread-1", bundle=2 : logging OFF
Figure 8.17 Delegating service proxy