如何在运行时通过 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 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.
}
}
这里有一个方法可以为您完成上述所有操作:
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))
我知道我可以(理论上)为我的包获取 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 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.
}
}
这里有一个方法可以为您完成上述所有操作:
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))