OSGi缓存使新安装的捆绑包保持已安装状态 我有一个C++程序,加载JVM并启动OSGi框架。OSGi框架是Equinox,更准确地说是org.eclipse.OSGi_3.8.1.v20120830-144521.jar 发射器 OSGi发射器是用JNI从C++调用的,它是这样的(细节被忽略):

OSGi缓存使新安装的捆绑包保持已安装状态 我有一个C++程序,加载JVM并启动OSGi框架。OSGi框架是Equinox,更准确地说是org.eclipse.OSGi_3.8.1.v20120830-144521.jar 发射器 OSGi发射器是用JNI从C++调用的,它是这样的(细节被忽略):,osgi,Osgi,现在,所有捆绑包都已解析,并且处于已解析、活动或已启动状态 从osgi.clean=true开始 如果我在osgiConfig映射中使用选项OSGi.clean=true启动OSGi框架,并将安装的bundle从一个运行更改为另一个运行,这将很好地反映在框架中 例如,如果使用bundleX和bundleY启动框架并调用 frameworkBundleContext.getBundles(); 那我就明白了 系统捆绑包(活动) bundleX(已解决) bundleY(已解决) 如果我关闭程

现在,所有捆绑包都已解析,并且处于
已解析
活动
已启动
状态

从osgi.clean=true开始 如果我在
osgiConfig
映射中使用选项
OSGi.clean=true
启动OSGi框架,并将安装的bundle从一个运行更改为另一个运行,这将很好地反映在框架中

例如,如果使用bundleX和bundleY启动框架并调用

frameworkBundleContext.getBundles();
那我就明白了

  • 系统捆绑包(
    活动
  • bundleX(
    已解决
  • bundleY(
    已解决
如果我关闭程序,这次使用bundleX和bundleZ重试,那么我看到了(毫不奇怪)

  • 系统捆绑包(
    活动
  • bundleX(
    已解决
  • bundleZ(
    已解决
在没有osgi.clean的情况下启动 如果我启动OSGi框架时没有在
osgiConfig
映射中设置
OSGi.clean
,那么安装的bundle会在不同的运行中停留,新的bundle不会被解析

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

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

  • 系统捆绑包(
    活动
  • bundleX(
    已解决
  • bundleY(
    已解决
  • bundleZ(
    已安装
    )(即尚未解决)
因此bundleX和bundleY在一次又一次的运行中幸存下来,无需第二次安装

另一方面,bundleZ不会自动解析。要使其达到
已解决
状态,我需要执行以下操作:

  final FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
  frameworkWiring.resolveBundles(null);
问题:我应该使用osgi.clean吗? 似乎每次使用
osgi.clean=true
都会给我一个新的开始,而不使用它意味着bundle状态可以在运行到运行之间存活下来。我想缓存可以让OSGi启动更快,但对我来说似乎没什么大不了的(因为我使用“reference:”前缀安装包,这意味着JAR不会复制到缓存中,只保留对原始文件位置的引用)

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


另外,如果有人能给我一个很好的解释,说明osgi.clean的确切含义以及osgi(Equinox)中的缓存是如何工作的,我将不胜感激。另外,请忽略起始级别。您缺少的步骤实际上是启动捆绑包

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

您用来启动bundle的任何其他方式都纯粹是运气使然,也就是说,因为这些bundle可能曾经在该状态下启动和缓存过。如果您在另一台计算机上安装了应用程序,则可能无法重复相同的状态。所以,实际上控制好你的捆绑包,自己动手


您通常不需要担心已安装和已解决之间的差异。Installed可以简单地表示“尚未解决”,例如,因为不需要捆绑包的导出。如果存在任何解决问题,例如缺少依赖项,那么在调用
start
方法时,您将以
BundleException
的形式了解这些问题。

忽略
osgi.clean
。另外,请忽略起始级别。您缺少的步骤实际上是启动捆绑包

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

您用来启动bundle的任何其他方式都纯粹是运气使然,也就是说,因为这些bundle可能曾经在该状态下启动和缓存过。如果您在另一台计算机上安装了应用程序,则可能无法重复相同的状态。所以,实际上控制好你的捆绑包,自己动手


您通常不需要担心已安装和已解决之间的差异。Installed可以简单地表示“尚未解决”,例如,因为不需要捆绑包的导出。如果存在任何解决问题,例如缺少依赖项,则在调用
start
方法时,您将以
BundleException
的形式了解这些问题。

如果忽略
osgi.clean
,则将自动安装以前安装的旧捆绑包。因此,我需要
osgi.clean
至少在我将配置更改为不加载特定捆绑包时,使Equinox忘记它们。关于“纯运气”语句,我遗漏的是,我仔细地为每个bundle设置了所需的
startlevel
(以控制启动顺序),还显式地启动了一个不会自动启动的bundle
/org.eclipse.equinox.console
)。好了,这正是Eclipse启动器和
org.Eclipse.equinox.simpleonfigulator所做的。示例中的bundle3是一个片段。我用关于开始级别的详细信息更新了原始问题。但是,设置开始级别实际上并不会导致bundle启动。它们仍然需要显式启动——只是如果启动的bundle高于当前的启动级别,那么它就不会实际启动
frameworkBundleContext.getBundles();
  final FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
  frameworkWiring.resolveBundles(null);