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

时间:2018-01-19 16:16:44

标签: osgi osgi-bundle

我知道我可以(理论上)获取我的包的Import-Package标头,解析它,并检查哪些包导出该包,但这似乎容易出错(似乎它甚至可能返回错误结果)。有没有更好的方法来找出我的捆绑依赖,而不是获取我当前的捆绑(通过FrameworkUtil.getBundle(ClassFromMyBundle.class)),检查Import-Package标题(通过调用Bundle.getHeaders().get("Import-Package")),并比较使用其他包导出的包导入的包(再次通过调用Bundle.getHeaders().get("Export-Package"))?

1 个答案:

答案 0 :(得分:3)

不要尝试解析和比较标头。相反,您可以使用捆绑包的BundleWiring来获取捆绑包所需的连线(具体根据所需的包)。  然后,您可以获取提供这些电线的捆绑包,以通过Import-Package获取捆绑所依赖的所有捆绑包的列表。

BundleWiring.getRequiredWires ( BundleRevision.PACKAGE_NAMESPACE )将返回为包提供包的所有必需BundleWire。然后,您可以在每个BundleWire上调用BundleWire.getProvider()以获取提供一个或多个这些包的包。但是,getRequiredWires(BundleRevision.PACKAGE_NAMESPACE)并不区分通过Import-Package标头和DynamicImport-Package标头导入的软件包。由于您只想查找Import-Package个依赖项,因此您需要检查BundleWire是否为动态依赖项。您可以通过检查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))