1

我有一个加载 JVM 并启动 OSGi 框架的 C++ 程序。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,ACTIVESTARTED状态。

从...开始osgi.clean=true

osgi.clean=true如果我在地图中使用选项启动 OSGi 框架osgiConfig并将安装的捆绑包从运行更改为运行,这很好地反映在框架中。

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

frameworkBundleContext.getBundles();

然后我看得很清楚

  • 系统捆绑包 ( ACTIVE)
  • 捆绑 X ( RESOLVED)
  • 捆绑Y ( RESOLVED)

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

  • 系统捆绑包 ( ACTIVE)
  • 捆绑 X ( RESOLVED)
  • 束 Z ( RESOLVED)

无开始osgi.clean

如果我在未osgi.clean在地图中设置的情况下启动 OSGi 框架,则已osgiConfig安装的捆绑包会在运行之间持续存在,并且不会解析新的捆绑包。

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

现在,当我重新启动osgi.clean并仅安装 bundleZ 时,我看到:

  • 系统捆绑包 ( ACTIVE)
  • 捆绑 X ( RESOLVED)
  • 捆绑Y ( RESOLVED)
  • bundleZ ( INSTALLED) (即尚未解决)

因此,bundleX 和 bundleY 从一次运行到另一次运行都幸存下来,而无需第二次安装。

另一方面, bundleZ 不会自动解析。为了让它达到RESOLVED我需要这样做的状态:

  final FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
  frameworkWiring.resolveBundles(null);

问题:我应该使用osgi.clean还是不使用?

似乎 usingosgi.clean=true每次都给了我一个新的开始,而不使用它意味着捆绑状态在运行中仍然存在。我猜缓存使 OSGi 启动得更快,但对我来说似乎没什么大不了的(因为我使用“reference:”前缀安装捆绑包,这意味着 jar 不会复制到缓存中,只是对原始文件的引用文件位置被保留)。

但是,我的应用程序是针对同一 OSGi 配置区域运行的多进程应用程序。osgi.clean=true在这种情况下一直运行是否有问题?

osgi.clean另外,如果有人能指出我对OSGi(Equinox)中缓存的确切含义和方式的一个很好的解释,我将不胜感激。

4

1 回答 1

1

忽略osgi.clean。也请忽略开始级别。您缺少的步骤实际上是启动捆绑包!

每次调用installBundle都会给你一个Bundle对象。安装完所有包后,您应该调用start()每个返回的包对象。

您用来启动捆绑软件的任何其他方式都完全取决于运气,即因为这些捆绑软件可能曾经在该状态下启动并缓存过。如果您将应用程序安装在另一台机器上,则可能无法重复相同的状态。所以实际上控制你的包并自己启动它们。

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

于 2013-09-18T18:58:01.723 回答