July 26, 2009 1 Comment
As I have already mentioned in my previous posts, we are using OSGi declarative services in Carbon to properly handle dependencies among bundles while keeping the expected dynamism. About one week back, when I was implementing a new feature in Carbon, I had to waste few hours due to two mistakes that I had made in using declarative services. So thought of sharing it as anybody can make these mistakes in declarative services.
We are using Equinox as the OSGi implementation which runs underneath Carbon. And also we are using felix maven-bundle-plugin to create bundles and felix maven-scr-plugin in using declarative services.
Now let’s move into the most important part. Think about a scenario in which you have a bundle A which registers an OSGi service called FooService and bundle B which uses this FooService. Now you have to write a declarative service component in B which contains the set and unset methods for FooService. As you might already know, you have to have an xml file which describes this declarative service, inside the OSGI-INF folder of your bundle. maven-scr-plugin generates this file for you if you have added correct annotations on the top of your declarative service component class. And also bundle B has to import the package in A which contains the FooService.
The two mistakes that I had done in my case are as follows.
- In my bundle B, the class which uses the FooService was missing. As I’ve mentioned above, we are using maven-bundle-plugin to generate the MANIFEST.MF file of our bundles. Bundle plugin only includes a package in the bundle if that package is exported or private packaged in the bundle. I had not done any of these. This is a simple mistake. But it’s really hard to find. This is because, OSGi environment doesn’t give any errors or exceptions and it shows that the declarative service component is satisfied. But the logic inside it never executes. OSGi environment can see the declarative service definition as it is in the xml file inside OSGI-INF folder. But the actual class is missing in this case.
- Say FooService is in org.example package in A. I had imported org.example package in B. But the declarative service component in B was never getting satisfied. The reason for this was I had another bundle C which exports the org.example package and bundle B had got wired with that bundle. To solve this problem, you have to remove that package export from C or properly version the package exported from A and import the same version from B.
Even though these are small mistakes, it’s not easy to identify these issues. It can waste your time and effort. Hope this will help..