I'm packaging a library as an OSGi bundle using maven-bundle-plugin
, which uses BND. I noticed BND generated a very long Export-Package
list, mainly because it includes many packages that are exported by the library itself in the uses
directive of other exported packages.
I (kind of) understand the uses
directive. I presume in this case classes of other packages (listed under uses
) are used in method signatures (therefore imported) by classes in the exported package.
In this sense, I have two questions:
uses
directive of an exported package? Those packages are not going to be exported by any other bundle; therefore no split packages.Here's how most exported packages are listed in the MANIFEST
Export-Package: org.lib.annotation;version="10",org.lib.coverage;version="10";
uses:="javax.measure.unit, org.lib.annotation,org.lib.geometry,org.lib.ref,org.
lib.ref.operation,org.ref.util"
From all packages in above uses
list, only javax.measure.unit
is imported from another bundle.
maven-bundle-plugin
configuration:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
<Export-Package>org.lib.*;version=${project.version}</Export-Package>
<Import-Package>*</Import-Package>
<_experiments>true</_experiments>
</instructions>
</configuration>
</plugin>
This appears to be correct, yes, although it's difficult to say for sure without more details of the code.
To answer your specific questions:
Yes, it is absolutely necessary to do this, because you cannot know that the packages are never going to be exported by another bundle. For one thing, bnd doesn't know this because it only looks at one bundle at a time. More importantly, there will probably be future versions of this bundle, in which case you are going to get multiple exports of the same packages. The uses
constraint is then essential to ensure that users of the packages cannot get hold of an inconsistent set of types.
To illustrate this, suppose you were to modify a class in one package, and then pass an instance of that class as a parameter into an old version of a class in another package. That old class would not understand the object you had given it. Actually the JVM itself will not let this happen, you will get a ClassCastException or a LinkageError... the OSGi uses
constraint just prevents us from getting this far.
I wouldn't say the packages are incorrectly defined as such. They are perhaps not well defined. The large number of uses
constraints indicates that the packages are highly coupled to each other and might benefit from some reorganising, i.e. moving tightly-coupled classes/interfaces into the same package, maybe merging some packages, etc. Also you don't really want circular dependencies between packages because that makes it difficult to factor out packages into separate modules. There is nothing OSGi-specific about this advice, incidentally.