如何在运行时通过 Import-Package 获取我的包所依赖的所有 OSGi 包?

How can I obtain all of the OSGi bundles that my bundle depends on via Import-Package at runtime?

我知道我可以(理论上)为我的包获取 Import-Package header,解析它,并检查哪些包导出该包,但这似乎容易出错(而且看起来它甚至可能 return 错误的结果)。没有比获取当前包(通过 FrameworkUtil.getBundle(ClassFromMyBundle.class))、检查 Import-Package header(通过调用 Bundle.getHeaders().get("Import-Package"))并比较导入的包与其他包导出的包(再次通过调用 Bundle.getHeaders().get("Export-Package"))?

请勿尝试解析和比较 headers。相反,您可以使用捆绑包的 BundleWiring 来获取捆绑包所需的线路(具体基于所需的包)。 然后您可以获得提供这些线路的捆绑包,以通过 Import-Package.

获取您的捆绑包所依赖的所有捆绑包的列表

BundleWiring.getRequiredWires(BundleRevision.PACKAGE_NAMESPACE) will return all the required BundleWires 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.
    }
}

这里有一个方法可以为您完成上述所有操作:

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);
}

此方法可用于获取当前包的依赖项,如下所示:

getBundlePackageImportDependencies(
    FrameworkUtil.getBundle(ClassFromYourBundle.class))