while doing tests I often see spurious "Illegal BundleContext"
exceptions at various places, mostly during shutdown of SC and
sometimes during startup.
Digging into the problem revealed that this is a race condition
during either bundle deactivation and/or bundle activation and
usage of bundles by other SC threads.
Just as an example here lets have a look at the UI bundle that
contains several services or can provide access to service
providers, like Systray service, history service etc. During
shutdown of SC several thing happen at several parallel threads:
- one thread (controlled by Felix) shuts down the bundles and calls
the stop method and stops the bundle
- another thread (initialized by SC) requires the Systray during
shutdown (this actually happens ) service and calls
GuiActivator.getSystrayService(...). If this method was never
called before in GuiActivator then GuiActivator calls
On modern multi-core systems both threads run parallel, not
pseudo-parallel as in single CPU/single core systems. At multi-core
systems we see more race conditions than at single core systems. In
the above example the bundle was stopped by Felix but the SC thread
calls the bundle to get the Systray service which leads to the
mentioned exception. This race condition is possible at single
core systems but on multi-core the chances are higher.
All activators in SC are not thread safe, they use the "bundleContext"
variable without checking for "null". Even during startup it may happen
1) Felix starts a bundle and thus also the services in that bundle.
2) These services may now access / requires services in other bundles
via the static methods in other activators using not initialized
bundleContext variables (I sometimes see the according NPE during
I don't know what the consequences are in such a case for the
requiring serives. This shouldn't happen during startup, this is why
the startup is ordered - but it seems to happen sometimes.
Some activators reimplement static methods to get commonly used
services, for example Resource service, configuartion service and
others. Is it possible to implement this in a global class
to avoid double coding (I'm not so familiar with the bundle contexts
and if the _same_ service has different instances at different bundles).