Java Reference
In-Depth Information
With this change, the bundle activator becomes trivial and just records the context:
public class Activator implements BundleActivator {
BundleContext m_context;
public void start(BundleContext context) {
m_context = context;
startTestThread();
}
public void stop(BundleContext context) {
stopTestThread();
}
}
Unfortunately, you're still not done, because there's a problem in the test method—can
you see what it is? Here's a clue: remember that services can disappear at any time, and
with a multithreaded application this can even happen between single statements.
The problem is that between the calls to getServiceReference() and get-
Service() , the Log Service could disappear. The current code assumes that when you
have a reference, you can safely dereference it immediately afterward. This is a com-
mon mistake made when starting with OSG i and an example of what's more generally
known as a race condition in computing. Let's make the lookup more robust by adding
a few more checks and a try-catch block, as in the following listing.
Listing 4.7 Correct lookup example
while (Thread.currentThread() == m_logTestThread) {
ServiceReference logServiceRef =
m_context.getServiceReference(LogService.class.getName());
if (logServiceRef != null) {
try {
LogService logService =
(LogService) m_context.getService(logServiceRef);
if (logService != null) {
logService.log(LogService.LOG_INFO, "ping");
} else {
alternativeLog("LogService has gone");
}
If null,
service was
removed
} catch (RuntimeException re) {
alternativeLog("error in LogService " + re);
} finally {
m_context.ungetService(logServiceRef);
}
} else {
alternativeLog("LogService has gone");
}
Ungets service
when not used
pauseTestThread();
}
The test method is now robust but not perfect. You react to changes in the Log Ser-
vice and fall back to other logging methods when there are problems finding or using
 
Search WWH ::




Custom Search