I know I could (in theory) obtain the Import-Package
header for my bundle, parse it, and check which bundles export that package, but that seems error prone (and it seems like it might even return the wrong results). Is there no better way to find out my bundle's dependencies than obtaining my current bundle (via FrameworkUtil.getBundle(ClassFromMyBundle.class)
), examining the Import-Package
header (by calling Bundle.getHeaders().get("Import-Package")
), and comparing the imported packages with packages exported by other bundles (again by calling Bundle.getHeaders().get("Export-Package")
)?
Do not try to parse and compare headers. Instead, you can use the BundleWiring
of your bundle to obtain the required wires of your bundle (based specifically on required packages).
Then you can obtain the bundles that provide those wires to get a list of all the bundles that your bundle depends on via Import-Package
.
BundleWiring.getRequiredWires
(
BundleRevision.PACKAGE_NAMESPACE
)
will return all the required BundleWire
s that provide packages to a bundle. Then you can call BundleWire.getProvider()
on each BundleWire
to obtain the bundle that provides one or more of those packages. However, getRequiredWires(BundleRevision.PACKAGE_NAMESPACE)
doesn't discriminate between packages imported via the Import-Package
header and the DynamicImport-Package
header. Since you only want to find Import-Package
dependencies, you'll need to check whether the BundleWire
is a dynamic dependency. You can do this by checking the directives of the BundleRequirement
:
BundleRequirement requirement = bundleWire.getRequirement();
if (requirement != null) {
Map<String, String> directives = requirement.getDirectives();
String resolution = directives.get("resolution");
if ("dynamic".equalsIgnoreCase(resolution)) {
// The dependency was obtained via DynamicImport-Package.
}
}
Here's a method that will do all of the above for you:
public static Set<Bundle> getBundlePackageImportDependencies(Bundle bundle) {
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
if (bundleWiring == null) {
return Collections.emptySet();
}
List<BundleWire> bundleWires =
bundleWiring.getRequiredWires(BundleRevision.PACKAGE_NAMESPACE);
if (bundleWires == null) {
return Collections.emptySet();
}
Set<Bundle> bundleDependencies = new HashSet<Bundle>();
for (BundleWire bundleWire : bundleWires) {
BundleRevision provider = bundleWire.getProvider();
if (provider == null) {
continue;
}
Bundle providerBundle = provider.getBundle();
BundleRequirement requirement = bundleWire.getRequirement();
if (requirement != null) {
Map<String, String> directives = requirement.getDirectives();
String resolution = directives.get("resolution");
if ("dynamic".equalsIgnoreCase(resolution)) {
continue;
}
}
bundleDependencies.add(providerBundle);
}
return Collections.unmodifiableSet(bundleDependencies);
}
This method can be used to obtain the dependencies of the current bundle like so:
getBundlePackageImportDependencies(
FrameworkUtil.getBundle(ClassFromYourBundle.class))