How to manage bundles/dependencies in embedded OSGi application?

375 Views Asked by At

I'm currently developing a plugin system in which I embed apache felix in my application. The plugins itself are the OSGi bundles. So far deploying the bundles works just fine but I have trouble interacting with my bundles/plugins. I tried two approaches:

  • Register the a service "Plugin" in my Plugin and use the service listener in my "host" application to interact with the plugins.

The service listener is not invoked and I can't cast the returned Plugin object because the Plugin.class of my Host application is a different one compared to the Plugin.class thats inside the bundle.

  • Register the "PluginManager" in the host application and load this manager in the bundle.

In this case I'm again unable to cast the service class because of this class "duplication" issue.

I understand why the classes are "duplicated" but I'm not sure what to do about it.

My current setup:

  • plugin-api maven module: Provides Plugin interface
  • app maven module: Contains the app which embeds Apache Felix
  • dummy plugin has only a dependency on plugin-api

Is there a problem with the way my setup is structured? How can I access host services without creating a class mess? Should I create another module which is used to compile my plugin but it is excluded from the bundle and later provided on the host via FRAMEWORK_SYSTEMPACKAGES_EXTRA?

1

There are 1 best solutions below

0
On BEST ANSWER

You should define your Plugin API (and all the non-VM based types that it uses) on the application side. If I would do this, I would make an API bundle (yes bundle) that exports these packages.

Make sure that all plugins not export the API or at least allow it to be imported.

In your application, before you start your Felix embedded framework, you get all the manifests of all JARs on the classpath with getResources("META-INF/MANIFEST.MF")and check for Export-Package. Then concatenate all these exported packages and set the OSGi Framework property org.osgi.framework.system.packages.extra to the joined string.

This will export any package on your classpath, so also your API bundle. Since the framework now exports these packages, your plugins will use the standard classpath as provider. Therefore, the API will have only one source and you will not get into class hell.