One of the ever recurring discussion in OSGi is about ordering during initialization. Ordering is the siren song that we are often so lured by as a shortcut to handle the actual dependencies. Ordering can work if you're the omnipotent god in your project and you can oversee all the details. However, for mere mortals it creates very brittle software that is highly unlikely to work in other environments. Just the fact that in OSGi any bundle can be stopped wreaks havoc with any ordering model. However, many are strengthened in their pursuit of simpleness when they discover the start level service! The start level service seems to offer ordering! Yes, it is clearly one of the pretty sirens!
However, the start level service is a tool of the deployer. Writing your code with the assumption that the deployer will setup all the bundles properly and handle all edge cases will only work when you're the deployer and you will never get sick. And even then, you'll likely spent a lot of time chasing dependency issues that could easily have been prevented.
And the only thing you really need is the mindset that dependencies should be explicit and managed. In OSGi, dependencies are handled through services and packages. Package dependencies make sure that you can build code on solid ground by ensuring that all your required code dependencies are managed. That is, you won't run if the classes are not available. So when your code runs, it has a well defined environment. However, this model is not suitable for the myriad of dependencies that we should handle in modern software. Log service is up? Do I get configuration? Is my communication provider up? Is there a properly initialized database? You know what I am talking about.
In non-OSGi software may of these dependencies are handled implicity with a lazy initialization model. This is one of the key reason that Spring became so succesful: it provide a model where you could specify all this ordering and configuration in just one place. Though this works amazingly well for monolithic applications, it does not scale so well with lots of independently developed components because all the ordering and configuration details must be handled centrally. Creating the so called "godess" spring file. In a large systen, there is a huge advantage to allow independent components to form the application. Independent components can be developed easier, can be made more robust, and allow the final application more flexibility in deployment. However, this requires that each component specifically states its dependencies.
It turns out that virtually any dependency can be mapped to the OSGi service model. It is a bit of a paradox, but because OSGi services are so unreliable, you can make extremely robust systems because real world dependencies are all too often dynamic. If you use OSGi services for all your dependencies, there is no need to use start level ordering to make the initialization work.
So what is the purpose of the start level service? Well, there are many cases where you can improve the performance or appearance of a system by ordering the initialization. For example, if one of your bundles is a flash image to show the system, then it has it advantages that this image is visible during the first second when your system starts. There is also the issue that some orderings are more smooth than others. Starting some strategic bundles first can make a significant improvement. However, this is the toy of the deployer and bundles that make assumptions about other bundles without explicitly handling them are just bad bundles ... however attractive startlevel number 2 might appear.
Peter Kriens
This comment has been removed by a blog administrator.
ReplyDelete