Java 如何正确处理ManagedServiceFactory中的异常?

Java 如何正确处理ManagedServiceFactory中的异常?,java,osgi,Java,Osgi,OSGi ConfigurationAdmin规范提到,ManagedService和ManagedServiceFactory的实现可能通过抛出ConfigurationException来发出无效传入配置的信号。然而,除了这一声明之外,规范没有说明各个参与者应该如何处理这种情况,最重要的是,在出现这种例外情况后,环境应该是什么状态 例如,假设一个ManagedServiceFactory当前有一个具有一组有效属性的服务实例(比如service.pid=example.12345);该服务实例

OSGi ConfigurationAdmin规范提到,
ManagedService
ManagedServiceFactory
的实现可能通过抛出
ConfigurationException
来发出无效传入配置的信号。然而,除了这一声明之外,规范没有说明各个参与者应该如何处理这种情况,最重要的是,在出现这种例外情况后,环境应该是什么状态

例如,假设一个
ManagedServiceFactory
当前有一个具有一组有效属性的服务实例(比如service.pid=example.12345);该服务实例由工厂发布到服务注册表中。然后,通知工厂该服务实例的配置更新;但是,在验证时,更新方法确定传入属性无效。因此,根据规范,工厂应抛出
ConfigurationException

但是,如果不做任何其他事情,环境仍然处于不稳定状态:现在注册中心中有一个基于不再存在的配置的已发布服务;因此,无论何时重新启动
ManagedServiceFactory
服务(例如,由于捆绑包更新或整个框架重新启动),都无法重新启动该服务,因为它以前的有效配置已丢失。这打破了配置管理子系统的持久性范式,并对某些OSGi环境的稳定性提出了严重的问题

不幸的是,初始configurator捆绑包无法轻松检测到其配置更改导致ConfigurationException,这使得从该位置恢复稳定的配置通常几乎不可能。在我看来,在这种情况下,ConfigurationAdmin(持续)恢复以前有效的配置更合适,但不幸的是,规范中没有提到这种行为,而且我在Felix的实现中没有看到任何这种机制的痕迹

鉴于这些事实,保持环境稳定性的唯一可能性似乎是
ManagedServiceFactory
实现首先取消注册并销毁已接收无效配置属性的现有服务实例,并且仅在此之后,抛出强制的
ConfigurationException
。这将有效地导致与在此时重新启动框架时相同的环境状态。类似地,
ManagedService
实现应该首先完全恢复其默认配置,然后抛出
ConfigurationException
来处理无效配置


那么,如何准确地处理
ManagedService
managedserviceFactory
配置更新中的错误呢?我的理解正确吗?从我在
ManagedService
ManagedServiceFactory
的示例/开源实现中看到的情况来看,大多数开发人员似乎完全忽略了这一方面。规范中是否对该问题进行了澄清?

一般策略是将其记录为错误,并祈祷它很快得到解决。配置异常的目的是向devops提供详细信息,以便能够快速更正

你所描述的策略是如此的复杂和开放,以至于他们往往会制造出比他们所能解决的更多的问题。有人错误地创建了错误的配置,唯一的解决方案是修复该配置。我发现处理这些特殊情况的一般系统变得非常脆弱。一旦出了问题,你就处在一个无限的空间中,软件在推理你不知道的事情时是非常糟糕的


因此,除非您有一些非常具体的用例,否则我认为它不能,也不应该有一个通用的解决方案。

通常有三种策略来处理这个问题:

  • 拒绝无效配置,但保留以前的状态
  • 拒绝无效配置并销毁当前状态,就像以前没有配置一样
  • 拒绝无效值,尽可能多地应用有效值
  • 选择什么,您描述如何抛出异常、在日志中打印警告、发送电子邮件或弹出窗口,这在很大程度上取决于您的系统和用例

    例如,如果您有一个用户界面,用户可以更改配置,则只需保存旧配置,如果检测到错误,则可以要求用户更正或还原配置

    更好的是,您可以使用描述配置需求,以便在应用配置之前验证配置


    如果您有一组配置文件,最好在备份之前进行备份,以便恢复:)

    我不同意“记录并祈祷它会得到解决”的策略。我的一些OSGi应用程序部署为嵌入式计算机,安装在客户的站点上。在这种情况下,“系统操作员”基本上指定一些仅具备基本技术知识的本地用户。期望他们在每次进行配置更新时正确地检查日志中的错误是一个太大的负担,最终的错误很可能不会被发现。让系统一开始看起来可以工作,但在用户不在时无法在以后重新启动是不可接受的……至于我描述的策略,它们实际上非常简单且可预测。他们不尝试修复无效的配置,而只是通过恢复以前的有效配置或将
    MangedService[Factory]
    重置为系统启动时的相同状态,使系统脱离灰色区域(即,系统似乎工作正常,但无法重新启动)