OSGi捆绑更新如何工作?

Sat*_*ish 23 osgi

当更新捆绑包(比如修复错误)时,当前使用正在更新的捆绑包的其他捆绑包会发生什么?

假设有两个捆绑服务和dao.假设当我发出更新dao层的命令时,服务包中的类正在使用dao包中的类.使用dao代码的服务层中的类是否会获得异常?


谢谢你的回复.

我的意思是用相同的版本更新.

直到发生包括依赖包的包刷新.

用户更新捆绑包会调用捆绑刷新操作,对吧?假设当用户调用refresh来更新dao bundle时,bundle服务中的一个类在dao层中的类上调用了一个方法......在这种情况下会发生什么?

我发现此博文有用:http: //solutionsfit.com/blog/2008/08/27/osgi-what-modularity-can-do-for-you-part-1/

从帖子:

如果我们只是用包含修复的包替换包,则容器将取消注册旧包并注册新包.然后,代理可以处理引用混洗并恢复服务调用.这种互动几乎是即时的.您的客户将完全忘记已发生的事情,您刚刚为公司节省了大量资金(我听到奖金吗?).

在这篇博文中,对authorizePayment()的调用被暂停,直到更新的bundle可用.当捆绑刷新发生时,如果控件在authorizePayment()方法内,会发生什么?

Pet*_*ens 20

Bundles有两种依赖:

  • 服务和
  • 类加载器之间的连接,由包名称键入.这些连接称为电线.

服务很容易撤回,因为这是他们设计的内在要素.导线较硬,因为它们在您的物体中错综复杂地编织而且这些物体不了解动态.因此,当您安装新捆绑包时,旧捆绑包会保持原样,您的对象不会更新,并且更新后的捆绑包仍会将其线路视为僵尸.

当您调用refreshPackages时,框架会查看这些依赖项并找到引用这些僵尸的bundle.然后停止每个僵尸.捆绑的合同是它应该清理.我们通过为您进行大量清理来帮助捆绑,但有些事情非常糟糕,例如将引用存储在其他bundle的静态中或忘记停止已启动的线程.通过其他方式依赖于这些捆绑包的其他捆绑包会收到捆绑停止的通知,因此他们也可以清理任何引用.捆绑包停止后,捆绑包将无法解析,然后再针对新捆绑包进行解析.

对于真正的OSGi包,清理是自然的,并且在您的代码中不是真的可见(因为它应该是).它得到了声明服务,iPOJO,依赖管理器,Spring,Blueprint等工具的很好支持.神奇的工作集中在μservices模型而不是dong类加载hacks.

为什么我们不自动刷新?好吧,我们曾经做过但刷新是破坏性的.在许多情况下,您需要更新多个捆绑包.每次更新后都会受到干扰,这将是不必要的痛苦.也就是说,在安装或更新之后,您应该始终进行刷新,但是您可以包含许多安装/更新.


小智 8

当您更新包,使用OSGi" 更新 "命令时,它是最有可能的是依靠它,已经从老版本的包捕获了一组加载类的其他依赖包.通常符合您在问题中描述的问题的情况.

为了避免此捆绑包所包含的类的不同版本之间可能存在不一致,OSGi容器决定暂时从外部世界隐藏新版本的更新捆绑包的类.您可以将其视为将更新的类与其他包隔离开来 - 暂时 - .

这里的要点是OSGi容器不能只是从新版本的目标包开始加载类,因为依赖包最终会看到它们已加载的类的旧版本,并与相同类的新版本混合使用更新后加载,这将导致不一致,导致无法控制的混乱.捆绑包卸载也是如此,捆绑包将从已安装的捆绑包列表中删除,但不会从内存中删除.它应该被保留,以便依赖包可以继续从中加载类.

因此,您可以将"update"命令视为引入同一捆绑包的新版本,提供给尚未出现的依赖捆绑包,这些捆绑包在更新时尚未存在.虽然在更新之前存在的旧版本仍保留在内存中,以确保向后兼容性并避免对已经开始依赖于更新的捆绑包的现有捆绑包造成任何可能的中断.

请注意,旧版本仅保留在内存中,这意味着重新启动服务器将导致根除所有这些旧版本并将最新版本带到表中.这是完全合理的,因为不需要向后兼容,因为所有捆绑包现在同时开始.

接下来会发生什么,你必须在特定的bundle上显式调用' refresh '命令,这取决于更新的bundle-,或者你可以选择运行'refresh'命令而不指定特定的bundle,意思是所有捆绑都将被盲目刷新.'refresh'命令强制重建目标bundle的依赖树,并强制它们的类加载器开始从头开始加载它们所需的类.

只有这时,依赖包才会开始看到您对已更新的包中的类的代码所做的更改.

规则是这样的

已导入旧版本类的现有已解决捆绑包不会自动重新连接到新捆绑包,除非它们已刷新.


BJ *_*ave 5

更新捆绑包时,会安装新版本(捆绑包的位).如果另一个bundle连接到更新的bundle的先前版本,也就是说,另一个bundle导入了一个由先前版本导出的包或另一个bundle需要先前版本的bundle,那么OSGi框架将保留更新的先前版本捆绑以服务来自依赖包的未来类加载请求,直到发生包括依赖包的包刷新.

这样做的目的是在更新依赖关系时最小化或延迟扰乱依赖束.管理代理可能希望更新多个捆绑包,最后执行捆绑刷新以"依赖"现代化.完成软件包刷新后,没有连接到更新的软件包的先前版本,OSGi框架现在可以自由地丢弃先前的修订版.

因此,在您的示例中,通常不会导致异常.但当然这取决于所讨论的代码实际上在做什么以及他们的捆绑清单是如何编写的.