java - 我们如何在运行时更新OSGI中的任何捆绑软件

标签 java maven osgi apache-felix osgi-bundle

在OSGI中,我们可以在运行时更新,激活,停用捆绑软件。

但是我不知道怎么可能,因为其他一些人可能会使用该捆绑软件的功能。为什么这种情况不会使应用程序崩溃?

通常,在JVM中,无论何时运行任何应用程序,它都会加载源类文件和所需的Java API类文件并产生结果。

您能解释一下OSGI的基本架构是什么,以便它允许上述情况发生。

最佳答案

要了解这一点,您需要查看OSGi格局的两个部分:服务和(Java)类/接口。

与服务相关的激活,停用和更新由客户端(用户)与服务提供者之间的合同处理。客户端必须跟踪对可用服务的更改,并在得知要删除该服务后立即释放对服务的使用。此外,一旦更好的服务可用,它就可以跟踪其他服务的可用性以更新其参考。请注意,OSGi环境是一种协作环境:非一个环境会强制使用包实际释放对服务的引用。因此,错误的行为可能导致意外的结果。

这样:对于服务,服务的用户负责处理服务可用性的动态。

与Java类/接口相关,意味着类加载,处理由框架本身完成。卸载为其他捆绑包提供类的捆绑包(通过其Export-Package清单条目宣布)时,捆绑包提供的类仍可用于已在使用它们的捆绑包。只有通过隐式告诉框架更新捆绑包之间的类的连接(通过对org.osgi.service.packageadmin.PackageAdmin服务的“刷新”操作,通常通过某种框架控制台提供),才能对捆绑包导入的类进行更改。在那种情况下,可以通过框架停用使用包,将其重新连接到由不同包提供的其他类,然后再次激活。

这样:对于类加载,除非明确要求这样做,否则框架不会更改初始接线。对于这些包,必须知道它们可以随时启动,加载,停止和卸载以处理变化的上下文。

也许有些情况使这一点更加清楚:
假设在包LogInterface中有一个接口定义Log。该接口提供了一种方法:logMessage(String message)。在此定义旁边,有一个捆绑包LogProvider,提供了接口的实现,而捆绑包则利用了接口LogUser的功能。这三个捆绑软件以捆绑软件和软件包版本1.0.0的形式在OSGi框架中安装和启动。捆绑包LogProvider在服务注册表中注册日志服务对象,捆绑包LogUser检索该服务对象并对其进行调用以进行日志记录。

场景1 :假定LogProvider软件包已更新,而没有更改接口定义,例如,不仅记录到控制台,而且记录到文件。在这种情况下,必须停止旧的LogProvider捆绑软件(版本1.0.0),并且必须将新的LogProvider捆绑软件(1.1.0)安装到框架中并启动。旧的LogProvider捆绑软件一旦停止,日志服务就会消失,并通知LogUser(必须释放服务对象)。启动新的LogProvider捆绑包后,LogUser捆绑包可以查找并使用LogProvider捆绑包1.1.0提供的新实现。

场景2 :假设接口定义中添加了一种新方法,该方法允许传递严重性代码。这意味着在logMessage(String message)方法旁边,Log接口获得了一个新方法logMessage(int severity, String message)。由于接口更改,因此将卸载捆绑LogInterface版本1.0.0,并安装并启动捆绑LogInterface版本1.1.0。当然,LogProvider捆绑包也必须更改以提供新方法的实现,因此必须安装并启动LogProvider版本1.3.0。
在这种情况下,卸载LogProvider 1.2.0并启动LogProvider版本1.3.0不会导致LogUser能够检索新提供的服务。这是因为LogProvider 1.3.0从LogInterface捆绑软件1.1.0中加载了Log接口的定义,并从LogInterface捆绑软件1.0.0中加载了LogUser。要将LogUser更新到新的接口版本,必须对LogUser捆绑软件进行捆绑刷新。在实践中,执行此“刷新”意味着LogUser捆绑包将停止,重新连接到新的LogInterface版本1.1.0捆绑包并重新启动。

关于java - 我们如何在运行时更新OSGI中的任何捆绑软件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21228056/

相关文章:

java - 有没有办法用唯一的配置文件编译类并以其他方式排除它?

osgi - 如何从非 OSGi 应用程序调用 OSGi 应用程序,反之亦然

java - 尽管有 Import-Package,但 org.osgi.framework.BundleActivator 的 ClassNotFoundException

java - java.util.Random 中的种子

Java:从 JInternalFrame 中获取InputMap(WHEN_IN_FOCUSED_WINDOW)

java-我需要一个仅在 while 循环中使用而不被分配的值

java - 更新 ObservableList 时线程挂起

maven - Gradle 构建失败,并显示“无法解析...${javassist.version}...路径中存在非法字符”

java - Maven:com.example.speech:speech-google-cloud-samples 的不可解析父 POM

java - 如何使用OSGI远程查看html文件