RCP development with bnd
About one and a half years ago we switched all our projects from using PDE together with Maven Tycho to bnd. The increase in development speed we reached was immense. Additionally bnd automatically pushed us towards writing better OSGi software. Over the time we experienced a lot of fallacies PDE unknowingly lead us to. One is, for example, the usage of the Require-Bundle declaration in the Manifest. A good Manifest with everything recommended for OSGi is nothing that can be achieved by a human, especially while the bundle is changing during development.
Since that time we actively preach the usage of bnd to anyone who is still using PDE. Together with the OSGi Alliance we held a lot of talks about this topic especially at the last two EclipseCon Europe in Ludwigsburg. The interest of the Eclipse community is huge and increasing, but unfortunately a big community is excluded from benefiting till now: developers of Eclipse Rich Clients. Bnd currently does not support a product export and wild hybrid solutions are necessary if one really wants to use bnd here. We always had a rough idea what needs to be done, but haven’t had the time to do it.
I finally found the time to tinker around a bit and made some progress in this area. It turns out, bnd is perfectly capable of supporting RCP development. I was able to start an RCP Application with an bndrun configuration and even export one. The OSGi Framework starts without any error, all the bundles are there and long dramatic pause no UI shows up.
What’s the issue?
As many might know, the Eclipse IDE the RCP is based upon, had its own module system before the implementation of OSGi in Eclipse 3. The Rich Client Platform still has a couple of remains of the initial migration left in its core. Active committers are sparse and thus manpower short. OSGi moved forward and most features are available in the latest releases of Eclipse. Unfortunately nobody saw fit to refactor these remains and thus RCP Developers always stick to the old ways, that turn out to be problematic and inefficient. I decided to write about these issues in another blog post, because this does not really concern the viability of bnd for RCP development. So, stay tuned for the upcoming fallacies in Eclipse RCP series.
But back to the Question: The main issue is the Eclipse launcher itself.
OSGi Launcher vs. Eclipse launcher
How does a OSGi Framework launcher roughly work? The launcher is usually a class with a static main. It reads some property file(s), that point to the framework jar and the initial set of bundles to be installed. The framework is then started via a standard mechanism, some properties set and the bundles are installed and started. There is a bit more to it, like basic logging, Permission or Error handling, but the launcher is essentially done after this point and the framework takes up the slack from here.
Equinox has a class called EclipseStarter that performs all the above mentioned tasks plus a lot more. As I looked into it I saw, that it performs a lot of operations that should be done inside the framework. These are for example:
- Equinox has a special EquinoxConfiguration that extends the standard EnvironmentInfo of OSGi. The arguments, held by this are set by the EclipseStarter and not by the framework.
- Bundles that are marked with Lazy start are started according to their configured StartLevel
- The defined Equinox Application will be started
What have I achieved so far?
For a start, I added all the bundles I found in my RCP to a bndrun, together with equinox as framework. This got me a running Framework, with all the bundles in it, but nothing happened. I additionally collected all the properties, that are spread over the eclipse.ini and config.ini and added them as well and … nothing happened either. Guess what, the points I made above are the problem. I thus created 2 bundles, that had a Component each that started immediately. One handles the setup of the above mentioned additional EquinoxConfiguration properties and the other one starts the EquinoxApplication. Here I hit the next wall, because no application could be found. The reason: The ExtensionRegistry hasn’t been started yet. Most bundles where in the state starting, because they are marked as start lazy. Thus I started the correct bundle manually before the start of the Application and everything worked like a charm.
Let’s see, where this leads. I will keep you posted!
by Ilenia Salvadori, Mark Hoffmann, Jürgen Albert