Java Reference
In-Depth Information
m_context = context;
Remembers
context for
later
startTestThread();
}
public void stop(BundleContext context) {
stopTestThread();
}
}
You also need to change the test method to always dereference the service, as in the
following listing.
Listing 4.5 Broken lookup example—testing the discovered Log Service
while (Thread.currentThread() == m_logTestThread) {
LogService logService =
(LogService) m_context.getService(m_logServiceRef);
Needs saved
bundle
context
if (logService != null) {
logService.log(LogService.LOG_INFO, "ping");
} else {
alternativeLog("LogService has gone");
}
If null,
service was
removed
pauseTestThread();
}
This is slightly better, but there's still a problem with the bundle activator. You discover
the Log Service only once in the start() method, so if there is no Log Service when
the bundle starts, the reference is always null . Similarly, if there is a Log Service at
startup, but it subsequently disappears, the reference always returns null from that
point onward. Perhaps you want this one-off check, so you can revert to another (non-
OSG i) logging approach based on what's available at startup. But this isn't flexible. It
would be much better if you could react to changes in the Log Service and always use
the active one.
A simple way of reacting to potential service changes is to always look up the ser-
vice just before you want to use it, as in the following listing.
Listing 4.6 Broken lookup example—potential race condition
while (Thread.currentThread() == m_logTestThread) {
ServiceReference logServiceRef =
m_context.getServiceReference(LogService.class.getName());
if (logServiceRef != null) {
((LogService) m_context.getService(logServiceRef)).log(
LogService.LOG_INFO, "ping");
} else {
alternativeLog("LogService has gone");
}
Safe to
dereference—
or is it?
pauseTestThread();
}
 
Search WWH ::




Custom Search