Java Reference
In-Depth Information
a service, but you can still miss Log Service implementations. For example, imagine
that a Log Service is available when you first call getServiceReference() , but it's
removed, and a different Log Service appears before you can use the original service
reference. The getService() call returns null , and you end up not using any Log
Service, even though a valid replacement is available. This particular race condition
can't be solved by adding checks or loops because it's an inherent problem with the
two-stage “find-then-get” discovery process. Instead, you must use another facility pro-
vided by the service layer to avoid this problem: service listeners.
4.3.2
Listening for services
The OSG i framework supports a simple but flexible listener API for service events. We
briefly discussed the listener pattern back in section 4.1.3: one object (in this case, the
framework) offers to send events to other objects, known as listeners. For services,
there are currently three different types of event, shown in figure 4.13:
REGISTERED —A service has been registered and can now be used.
MODIFIED —Some service metadata has been modified.
UNREGISTERING —A service is in the process of being unregistered.
reg
ctx.registerService(...)
reg
.setProperties(...)
reg
.unregister()
OSGi
service
registry
OSGi
service
registry
OSGi
service
registry
Figure 4.13
OSGi service
events
Registered
Modified
Unregistering
Every service listener must implement this interface in order to receive service events:
public interface ServiceListener extends EventListener {
public void serviceChanged(ServiceEvent event);
}
How can you use such an interface in the current example? You can use it to cache
service instances on REGISTERED events and avoid the cost of repeatedly looking up
the Log Service, as you did in section 4.3.1. A simple caching implementation may go
something like the following listing.
Listing 4.8 Broken listener example—caching the latest service instance
class LogListener implements ServiceListener {
public void serviceChanged(ServiceEvent event) {
switch (event.getType()) {
case ServiceEvent.REGISTERED:
m_logService = (LogService)
m_context.getService(event.getServiceReference());
break;
 
Search WWH ::




Custom Search