Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[riena-dev] Race Condition on Client Startup

Hello everybody,
 
this week, I encountered a nasty race condition between bundles on the startup of a riena client. The situation was as follows:
1.) Some weeks ago, I wrote my own extension of "org.eclipse.riena.communication.core.remoteservicefactory" to provide a new communication protokoll "local" to be able to redirect service calls to a local implementation (mainly for testing purpose, but also valid for a printing service).
2.) I wrote a test bundle that uses a 'local' service and started everything with an OSGi Frameword runner. Everything worked fine.
3.) Now I integrated everything in our riena client and suddenly all my services were null, even the remote ones. Surprinsingly I never got any exception.
 
After debugging the riena client I discovered the following race condition:
- The bundle "org.eclipse.riena.security.client.startup" defines an "org.eclipse.riena.core.startups" extension point and is thus started very early from the riena core.
- Its activator registers two remote proxy objects for the IAuthenticationService.
- During that registration the very first RemoteServiceFactory is created, calling "Inject.extension(IRemoteServiceFactoryProperties.EXTENSION_POINT_ID)".
- The Injector resolves all extensions for the extension point and therefore loads the class of my own factory.
- Now comes the nasty part: The EclipseLazyStarter detects in its method postFindLocalClass that another ClasspathManager exists on the activation stack and therefore calls secureAction.start(bundle, Bundle.START_TRANSIENT);
- That call triggers the Activator of my own communication bundle. In that activator all remote and local services are loaded and remote proxies are created. Unfortunately, the factories for the proxies are not ready yet.
- The method RemoteServiceFactory#createProxy cannot find a matching protocol and thus returns null.
- The fallback is to call RemoteServiceFactory#createLazyProxy. But that method fails in my environment, because it uses the ClassLoader of the RemoteServiceFactory class and that classloader does not know the service class (the current context classloader would know it!).
- I end up with a null value for all my service proxies.
 
 
I worked around this race condition by splitting my bundle into two: the first bundle contains everything for the local protocol, the second one contains the activator for creating the proxy object. Due to this split the first bundle can be fully activated and thus the protocols can be registered, before the second bundle starts.
 
Another solution could be to create the two needed IAuthenticationService proxies as lazy proxies, but I have not tried it.
 
I hope my mail will help, if anybody encounters a similar race condition.
 
Best regards,
Olaf Fricke

Back to the top