OSGi缓存将新安装的bundle保留为INSTALLED状态

时间:2013-09-18 15:07:34

标签: osgi

我有一个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);
    }
}

现在,所有捆绑包都已解析,并且处于RESOLVEDACTIVESTARTED状态。

osgi.clean=true

开始

如果我在osgi.clean=true映射中使用选项osgiConfig启动OSGi框架,并将从run to run安装的bundle更改为在框架中很好地反映出来。

如果我是用bundleX和bundleY启动框架并调用

frameworkBundleContext.getBundles();

然后我看到了

  • 系统包(ACTIVE
  • bundleX(RESOLVED
  • bundleY(RESOLVED

如果我关闭程序并使用bundleX和bundleZ重试这一次,那么我看到(毫不奇怪)

  • 系统包(ACTIVE
  • bundleX(RESOLVED
  • bundleZ(RESOLVED

osgi.clean

开始

如果我在osgi.clean地图中没有设置osgiConfig的情况下启动OSGi框架,那么已安装的软件包会在运行之间保持不变,并且新的软件包无法解析。

假设我运行一次osgi.clean=true加载bundleX和bundleY,然后关闭程序。

现在,当我在没有osgi.clean的情况下重新启动并仅安装bundleZ时,我看到了:

  • 系统包(ACTIVE
  • bundleX(RESOLVED
  • bundleY(RESOLVED
  • bundleZ(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)中的缓存如何工作的一个很好的解释,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

忽略osgi.clean。另请忽略开始等级。您缺少的步骤实际上就是开始捆绑!

每次调用installBundle都会为您提供Bundle个对象。安装完所有软件包之后,应该在每个返回的软件包对象上调用start()

您一直用来启动捆绑包的任何其他方式都归功于纯粹的运气,即因为这些捆绑包可能曾经在该状态下启动和缓存。如果您将应用程序安装在另一台计算机上,则相同的状态可能不会重复。所以实际上控制你的捆绑并自己启动它们。

您通常无需担心INSTALLED和RESOLVED之间的区别。安装可以简单地表示“未解决尚未”,例如因为不需要捆绑的出口。如果存在任何解决问题,例如缺少依赖项,那么在调用BundleException方法时,您会发现它们为start