我们如何在运行时更新OSGI中的任何包

dev*_*sda 4 java osgi maven apache-felix osgi-bundle

在OSGI中,我们可以在运行时更新,激活,停用软件包.

但我不明白它是如何可能的,因为其他一些人可能会使用这个包的功能.为什么不发生这种情况会导致应用程序崩溃?

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

你能解释一下OSGI的基本架构是什么,以便它能够实现上述目标.

Ari*_*den 5

要理解这一点,您需要查看OSGi环境的两个部分:服务和(Java)类/接口.

服务相关,激活,停用和更新由客户端(用户)和服务提供者之间的合同处理.客户端必须跟踪对可用服务的更改,并在收到服务即将被删除的通知后立即释放服务的使用.此外,它可以跟踪其他服务的可用性,以便在有更好的服务可用时立即更新其参考.请注意,OSGi环境是合作的:非一个强制使用bundle实际释放对服务的引用.因此,不正确的行为可能导致意外结果.

因此:对于服务,服务的用户负责处理服务可用性的动态.

与Java类/接口相关,意味着类加载,处理由框架本身完成.如果未安装向其他bundle提供类的bundle(如通过其Export-Package清单条目所宣布的那样),则捆绑包提供的类仍可供已使用它们的bundle使用.只有隐式告诉框架更新bundle之间的类连接(通过服务上的"刷新"操作org.osgi.service.packageadmin.PackageAdmin,通常通过某种框架控制台提供),才会对bundle导入的类进行更改.在这种情况下,框架可以停用使用捆绑包,重新连接到由不同捆绑包提供的其他类并再次激活.

因此:对于类加载,除非明确告知,否则框架不会更改初始布线.因为捆绑包必须意识到它们可以随时启动,加载,停止和卸载以处理不断变化的上下文.

也许某些场景使这更加清晰:假设Log在捆绑LogInterface中有一个接口定义.该接口提供了一种方法:logMessage(String message).在这个定义的旁边,有一个包LogProvider,它提供了一个接口的实现,以及一个利用接口LogUser功能的.这三个软件包在OSGi框架中作为软件包和软件包版本安装和启动1.0.0.Bundle 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 bundle 1.1.0 加载Log接口的定义,从LogInterface bundle 1.0.0 加载LogUser.要将LogUser更新为新接口版本,必须对LogUser捆绑包执行捆绑软件刷新.实际上,执行此"刷新"意味着将停止LogUser捆绑包,重新连接到新的LogInterface 1.1.0版捆绑包并重新启动.