OSGi: programmatically add imports to a bundle

2019-08-07 14:48发布

问题:

How can I add packages to a bundle's import from within code? I need it since I use libraries which rely on reflection and require other packages and I don't want to need to manually add those packages to MANIFEST.MF for each bundle I develop

回答1:

You cannot. Import-Packages are evaluated in the Resolution phase. (Phases are Installed -> Resolved -> Active ).

Your code is executed when the bundle is Active, therefore too late to add Import-Packages.

You can do 2 things:

  • Import-Package the packages you're going to use
  • Use the Dynamic-ImportPackage property to specify packages whose resolution can be deferred to execution time


回答2:

In addition to Filippo's solution, you can try to invert the dependency. F.i. instead of calling and inspecting the other bundles, you can let the bundles do that. Another way would be using a bundle tracker and obtaining the ClassLoader of the Bundle tracked. With this class loader you can act "as the bundle", so you don't need the Import-Package clause anymore.

When I started using OSGi, this was one of the first requirements I came up. Over time, I realized that in almost all cases, there is a cleaner and more consistent solution. So, think about it, if you really need this dependency. Is there no way to invert or abstract it to create a generic solution?

If nothing helps (as a last resort), you can also create (in Memory) a fragment with your core bundle as host, providing the required imports. The BundleContext offers you a method to load a bundle from a stream. You then have to update and call refreshpackages(via PackageAdmin service) on your host bundle in order to get the updated ClassLoader (implies a restart of your bundle). However, at the end, you'll have access to all your packages.

As a side note, I would not recommend to manipulate your host bundle by tweaking the import statement and then update... This renders your bundle indeterministic and won't work with signed bundles. Also, this is against everything one expects from OSGi (imagine a growing bundle over time... you need to shrink the imports at some point as well!!!)

Cheers, Mirko