我想从OSGI包中启动OSGI包。正如您所看到的,此代码通过从目录部署它来启动bundle:
private void installStartBundle(BundleContext bc, String location, String name) throws BundleException
{
debug("installing " + location + "...");
Bundle[] all = bc.getBundles();
for (Bundle bundle : all)
{
String l = bundle.getLocation();
if (l.indexOf(name) != -1)
{
debug("already installed bundle " + bundle.getBundleId() + "|" + bundle.getLocation() + ">" + bundle.getSymbolicName());
return;
}
}
Bundle b = bc.installBundle(location);
debug("starting " + b.getSymbolicName());
b.start();
}
我注意到一个问题:例如,我有一个包含xml配置文件和主包的包,它通过将xml配置文件部署到Felix并将包访问到xml包中来加载xml配置文件。
我可以从bundle成功安装bundle,但是依赖包的导出包不可访问。也许部署过程太慢,捆绑加载器无法找到导出的包。知道如何解决这个问题吗?
P.S你能告诉我如何检查一个捆绑包是否在Felix中成功部署?
答案 0 :(得分:5)
请注意,BundleContext具有以下功能:
BundleContext.getBundle(String location);
如果您使用该功能,则无需遍历所有捆绑包。
请检查OSGi中bundle的生命周期,了解它的安装和启动方式。要获得良好的效果,请访问http://zenit.senecac.on.ca/wiki/index.php/OSGi_Concepts_Bundle_Life-Cycle。
要知道安装捆绑包后到底发生了什么,请参阅功能的javadoc:http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#installBundle%28java.lang.String,%20java.io.InputStream%29
尽管我记得,在调用此函数后,bundle将保持INSTALLED状态(遗憾的是,我不清楚Javadoc)。您可以使用以下代码段强制解析捆绑包:
Bundle systemBundle = bundleContext.getBundle(0);
FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
frameworkWiring.resolveBundles(Arrays.asList(new Bundle[] {bundle}));
有关详细信息,请参阅resolveBundles函数的javadoc:http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/wiring/FrameworkWiring.html#resolveBundles%28java.util.Collection%29
请注意,即使您解析了捆绑包,其他可以连接到新捆绑包的捆绑包也不会这样做。例如。如果他们有一个可选的import-package,或者他们已经连接到其他bundle,那么什么都不会发生。要强制重新布线,您应该调用FrameworkWiring.refreshBundles功能。如果不清楚,您应该将哪个bundle作为参数传递,只需使用null参数调用refresh。
“我可以从捆绑包中成功安装捆绑包,但依赖包中导出的包不可访问”:
我不知道你是如何得出这个结论的。如果您在另一个包中有可选包导入,则可能是您没有强制刷新。
在捆绑包上调用start后(如果你有一个Fragment包,你不应该调用start,但只刷新),它应该处于ACTIVE状态。如果在调用BundleActivator期间发生异常或者bundle是Fragment包,它将保持RESOLVED。