【问题标题】:OSGi real advantageOSGi 真正的优势
【发布时间】:2018-10-10 15:02:21
【问题描述】:

我正在尝试使用 OSGi 来构建模块化 IoT 单元。如果想在不牺牲通信代码的情况下更新系统的某些部分(例如传感器代码),反之亦然,这似乎是一种完美的技术。

问题是:

为什么在更新服务时需要重新启动所有依赖的捆绑包(在捆绑包内)?

private void updateBundle(String f) {
    BundleContext mainBc = felix.getBundleContext();
    Bundle bundle = mainBc.getBundle(f);
    try {
        bundle.update();
    // if I don't do this, the services inside 'bundle' will NOT be updated
        PackageAdmin pa = mainBc.getService(mainBc.getServiceReference(PackageAdmin.class));
        pa.refreshPackages(mainBc.getBundles());
    // at this point all bundles were restarted
    } catch (BundleException e) {
        System.err.println("Error while updating  " + f);
        e.printStackTrace();
    }
}

从我的所有捆绑包都重新启动(或至少依赖的捆绑包)这一事实来看,更新捆绑包中的类定义有什么意义,因为所有应用捆绑包都将stoppedstarted 重置所有状态和活跃的连接?

这就像从命令行重新启动我的应用程序一样,为什么我需要 osgi?

【问题讨论】:

    标签: osgi apache-felix osgi-bundle


    【解决方案1】:

    看起来包含服务接口类的包是由您的服务实现包导出的。因此,当服务实现包更新时,导出的包也会更新。因此,所有使用该服务的包都使用导出包的旧版本,这与您的服务实现包不同。因此,您必须刷新所有这些服务消费包,以确保它们使用与您的服务实现包相同的导出包修订版。

    这就是为什么要从与服务实现包不同的包中导出包含服务接口类的包的原因。然后所有服务消费包服务实现包从导出包中导入包。那么当你更新服务实现包时,你就不需要刷新服务消费包了。

    因此,通常情况下,您不希望可能经常更新的包导出包,而这些包必须由关心更新包功能的其他包(例如服务)导入。

    【讨论】:

    • 听起来不错。而且我需要为我的应用程序的每个“模块”(从概念上讲)创建 2 个捆绑包。 1 个包含服务接口类的包和 1 个包含服务实现类的包。这样,当我更新实现时,我只需要重新启动这两个......好吧,我会试一试。
    • 好的,在这方面似乎工作正常。不过还有一个问题。如果我想更新一个模块,我调用bundle.update() 这会触发重启,但为了刷新依赖包我运行packageAdmin.refreshPackages() 这也会导致重启。是否有不触发重启两次的解决方法?
    • 你可以停止捆绑,更新捆绑,刷新包,然后重新启动捆绑。但是如果你将你的实现分离到它自己的包中,它甚至可能不会导出任何包,因此在它上面调用刷新包是没有意义的。您只需要在更新导出包并且希望刷新导入包时执行刷新包。
    • 没错。关于如何仅通过引用捆绑包来测试捆绑包是否正在导出包的任何想法?这是为了仅在需要时刷新包
    • bundle.adapt(BundleWiring.class) 将返回捆绑包的 BundleWiring 对象,然后您可以向 BundleWiring 询问导出的包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 2010-09-06
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多