Question

Can someone explain to me the rationale behind BND's exporting api packages that a bundle doesn't have. It seems just wrong to me, it always (AFAICT) results in ClassNotFoundException

Especifically
bundle A contains com.foo.api.MyInterface
bundle B contains com.foo.impl.InterfaceImpl which implements MyInterface

So if I tell bnd to export package com.foo in bundle A he will correctly export com.foo.api, but if i tell export package com.foo in bundle B it will incorrectly export com.foo.api, so consumers of MyInterface get wired to bundle B and then at runtime get a ClassNotFoundException

Why doesn't BND guarantee that when a bundle exports a package it actually contains it??

I know that if I export com.foo.api and com.foo.impl instead of just com.foo then the problem is solved in my trivial example, but in our real system this is not really a posibility. Also, the actual question is why BND does that, not how to fix the problem. i already know workarounds to solve the problem

Était-ce utile?

La solution 3

I have not yet worked with bnd directly but through the maven bundle plugin which should be fairly similar. What I found is that if you export a package you do not have then bnd will embed the classes of this package inside your bundle jar.

So at least when using the maven bundle plugin bundle B should have the interface embedded when the export of com.foo.api is defined. Not sure what happens when you define only the parent package as export but I would assume the same happens.

This automatic embedding can be quite useful if you want to deploy the api together with each bundle which I do not do regularly but which seems to be a kind of best practice in OSGi (for example for bundles that implement OSGi apis).

Autres conseils

This is just a feature of the bnd syntax. Because bnd has the option to embed imported packages, it considers the whole classpath when determining Export-Package and Private-Package headers. Bnd doesn't make any distinction between classes which are physically local to a folder being processed and others elsewhere on the classpath.

So if your Export-Package statement encompasses packages bnd knows about, bnd will assume you want to embed and export them. I'm surprised you're seeing exceptions, though, since bnd should also physically include the exported classes in the packaged bundle.

Did you look in bundle B to see that com.foo.api is not in there? If you tell bnd that bundle B should export com.foo.api, then bnd will actually put that package in bundle B and then export it. bnd has the "power" to include classes from anywhere in the -buildpath in the generated bundle. I think you really don't want bundle B to include and export com.foo.api, so you should modify your bnd file to remove the export statement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top