当更新捆绑包(比如修复错误)时,当前正在使用正在更新的捆绑包的其他捆绑包会发生什么?
假设有两个捆绑服务和dao。假设当我发出更新dao层的命令时,服务包中的类正在使用dao包中的类。使用dao代码的服务层中的类是否会获得异常?
感谢您的response。
我的意思是说使用相同版本更新。
直到发生包括依赖包的包刷新。
用户更新捆绑包会调用捆绑刷新操作,对吧?假设当用户调用refresh来更新dao包时,bundle服务中的一个类在dao层中的类上调用了一个方法...在这种情况下会发生什么?
我发现此博文有用: http://solutionsfit.com/blog/2008/08/27/osgi-what-modularity-can-do-for-you-part-1/
来自帖子:
如果我们只是用包含修复程序的bundle替换bundle,则容器将取消注册旧bundle并注册新bundle。然后,代理可以处理引用混洗并恢复服务调用。这种互动几乎是即时的。您的客户将完全忘记已发生的事情,您刚刚为公司节省了大量资金(我是否听说过奖金?)。
在这篇博文中,对authorizePayment()的调用被暂停,直到更新的bundle可用。当捆绑刷新发生时,如果控件在authorizePayment()方法内,会发生什么?
答案 0 :(得分:20)
Bundles有两种依赖关系:
服务很容易撤回,因为这是他们设计的内在要素。导线较硬,因为它们在您的物体中错综复杂地编织而且这些物体不了解动态。因此,当您安装新捆绑包时,旧捆绑包会保持原样,您的对象不会更新,并且更新后的捆绑包仍会将其线路视为僵尸。
当你调用refreshPackages时,框架会查看这些依赖项,并找到引用那些僵尸的bundle。然后停止每个僵尸。捆绑的合同是它应该清理。我们通过为您进行大量清理来帮助捆绑,但有些事情非常糟糕,例如将引用存储在其他bundle的静态中或忘记停止已启动的线程。通过其他方式依赖于这些捆绑包的其他捆绑包会收到捆绑停止的通知,因此他们也可以清理任何引用。捆绑包停止后,捆绑包将无法解析,然后再次针对新捆绑包进行解析。
对于真正的OSGi捆绑包,清理是自然的,并且在代码中不是真的可见(应该是这样)。它得到了声明服务,iPOJO,依赖管理器,Spring,Blueprint等工具的良好支持。神奇的重点是μservices模型而不是dong类加载hacks。
为什么我们不自动刷新?好吧,我们曾经做过但刷新是破坏性的。在许多情况下,您需要更新多个捆绑包。每次更新后都会受到干扰,这将是不必要的痛苦。也就是说,在安装或更新之后,您应该总是进行刷新,但是您可以包含许多安装/更新。
答案 1 :(得分:8)
当您使用OSGi' 更新 '命令更新捆绑包时,最有可能拥有其他依赖捆绑包且已捕获集合的依赖捆绑包从旧版本的bundle中加载的类。通常符合您在问题中描述的问题的情况。
为了避免此捆绑包所包含的类的不同版本之间可能存在不一致,OSGi容器决定暂时从外部世界隐藏新版本的更新捆绑包的类。您可以将其视为将更新的类与其他包隔离开来 - 暂时 - 。
这里的要点是OSGi容器不能只是从新版本的目标bundle开始加载类,因为依赖的bundle最终会看到他们已经加载的类的旧版本,并与新版本的在更新之后加载的相同类,其将包含将导致无法控制的混乱的不一致性。捆绑包卸载也是如此,捆绑包将从已安装的捆绑包列表中删除,但不会从内存中删除。它应该被保留,以便依赖包可以继续从中加载类。
因此,您可以将'update'命令视为引入相同捆绑包的新版本,将仅提供给尚未到来的依赖捆绑包,但尚未存在在更新时 - 。虽然旧版本 - 在更新之前存在 - 仍然是在内存中,以确保向后兼容性并避免对已经开始依赖于更新的捆绑包的现有捆绑包造成任何可能的中断。
请注意,旧版本仅保留在内存中,这意味着重新启动服务器将导致根除所有这些旧版本并将最新版本带到表中。这非常有意义,因为不需要向后兼容,因为所有捆绑包现在都在同一时间开始..
接下来发生的事情是,您必须在特定的捆绑包上明确调用“ 刷新 ”命令,这取决于更新的捆绑包,或者取而代之您可以选择运行'refresh'命令而不指定特定的包,这意味着所有包都将被盲目刷新。 'refresh'命令强制重建目标包的依赖树,并强制它们的类加载器开始从头开始加载它们所需的类。
只有依赖的捆绑包才会开始看到您对已更新的捆绑包中的类代码所做的更改。
规则是
现有已解密的捆绑包已导入旧版本的类,除非刷新,否则不会自动重新连接到新捆绑包。
答案 2 :(得分:5)
更新捆绑包时,会安装新版本(捆绑包的位)。如果另一个bundle连接到更新的bundle的先前版本,也就是说,另一个bundle导入了一个由先前版本导出的包或另一个bundle需要先前版本的bundle,那么OSGi框架将保留更新的先前版本捆绑服务从依赖包中提供未来类加载请求,直到发生包括依赖包的包刷新。
这样做的目的是在更新依赖关系时最小化或延迟扰乱依赖束。管理代理可能希望更新多个捆绑包,最后执行捆绑刷新以“依赖”现代化。捆绑刷新完成后,没有连接到更新捆绑包的先前版本,OSGi框架现在可以自由地丢弃先前版本。
因此,在您的示例中,通常不会导致异常。但当然这取决于所讨论的代码实际上在做什么以及他们的捆绑清单是如何编写的。