我有一个C ++程序,可以加载JVM并启动OSGi框架。 OSGi框架是Equinox,更确切地说是org.eclipse.osgi_3.8.1.v20120830-144521.jar
。
OSGi启动程序是使用JNI从C ++调用的,它是这样的(为了简洁省略了详细信息):
// Create OSGi framework.
final ServiceLoader<FrameworkFactory> frameworkFactoryLoader =
ServiceLoader.load(FrameworkFactory.class);
final FrameworkFactory frameworkFactory =
getFrameworkFactory(frameworkFactoryLoader);
final Map<String, String> osgiConfig = ...
final Framework osgiFramework = frameworkFactory.newFramework(osgiConfig);
// Start the framework.
osgiFramework.start();
// Install some bundles.
final BundleContext frameworkBundleContext = osgiFramework.getBundleContext();
final Bundle bundle1 =
installBundle(frameworkBundleContext, "reference:" + bundle1URI, null);
installBundle(frameworkBundleContext, "reference:" + bundle2URI, 5);
installBundle(frameworkBundleContext, "reference:" + bundle3URI, 10);
...
// Explicitly starting a particular bundle.
bundle1.start();
...
// Raise the framework start level so bundles are started
// at the desired start levels.
final FrameworkStartLevel frameworkStartLevelObject =
bundleAdapt(systemBundle, FrameworkStartLevel.class);
frameworkStartLevelObject.setStartLevel(10, ...left-out...);
安装捆绑包的辅助函数如下:
private Bundle installBundle(final BundleContext frameworkBundleContext,
final String bundleURI,
final Integer desiredStartLevel) {
final Bundle bundle = frameworkBundleContext.installBundle(bundleURI);
if (desiredStartLevel != null) {
// Set the level at which the bundle should start.
// (Otherwise, it will start at the default level.)
final BundleStartLevel bundleStartLevel =
bundleAdapt(bundle, BundleStartLevel.class);
bundleStartLevel.setStartLevel(desiredStartLevel);
}
}
现在,所有捆绑包都已解析,并且处于RESOLVED
,ACTIVE
或STARTED
状态。
osgi.clean=true
如果我在osgi.clean=true
映射中使用选项osgiConfig
启动OSGi框架,并将从run to run安装的bundle更改为在框架中很好地反映出来。
如果我是用bundleX和bundleY启动框架并调用
frameworkBundleContext.getBundles();
然后我看到了
ACTIVE
)RESOLVED
)RESOLVED
)如果我关闭程序并使用bundleX和bundleZ重试这一次,那么我看到(毫不奇怪)
ACTIVE
)RESOLVED
)RESOLVED
)osgi.clean
如果我在osgi.clean
地图中没有设置osgiConfig
的情况下启动OSGi框架,那么已安装的软件包会在运行之间保持不变,并且新的软件包无法解析。
假设我运行一次osgi.clean=true
加载bundleX和bundleY,然后关闭程序。
现在,当我在没有osgi.clean
的情况下重新启动并仅安装bundleZ时,我看到了:
ACTIVE
)RESOLVED
)RESOLVED
)INSTALLED
)(即尚未解决)因此,无需第二次安装,bundleX和bundleY就可以从一次运行中幸存下来。
另一方面,bundleZ不会自动解决。为了使其达到RESOLVED
状态,我需要这样做:
final FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
frameworkWiring.resolveBundles(null);
osgi.clean
吗?似乎使用osgi.clean=true
每次给我一个新的开始,而不使用它意味着捆绑状态从一次运行中幸存下来。我想缓存会让OSGi启动得更快,但对我来说似乎不是什么大问题(因为我使用“reference:”前缀安装捆绑包,这意味着jar不会被复制到缓存中,只会引用原始的文件位置保留。)
但是,我的应用程序是针对相同OSGi配置区域运行的多进程应用程序。在这种情况下,始终使用osgi.clean=true
运行是否存在问题?
此外,如果有人能够指出我对osgi.clean
的确切含义以及OSGi(Equinox)中的缓存如何工作的一个很好的解释,我将不胜感激。
答案 0 :(得分:1)
忽略osgi.clean
。另请忽略开始等级。您缺少的步骤实际上就是开始捆绑!
每次调用installBundle
都会为您提供Bundle
个对象。安装完所有软件包之后,应该在每个返回的软件包对象上调用start()
。
您一直用来启动捆绑包的任何其他方式都归功于纯粹的运气,即因为这些捆绑包可能曾经在该状态下启动和缓存。如果您将应用程序安装在另一台计算机上,则相同的状态可能不会重复。所以实际上控制你的捆绑并自己启动它们。
您通常无需担心INSTALLED和RESOLVED之间的区别。安装可以简单地表示“未解决尚未”,例如因为不需要捆绑的出口。如果存在任何解决问题,例如缺少依赖项,那么在调用BundleException
方法时,您会发现它们为start
。