OSGi和...?我用什么来控制装载/卸载/重新装载包装?

OSGi和...?我用什么来控制装载/卸载/重新装载包装?

问题描述:

我有一个庞大的应用程序和库的生态系统,目前作为各种应用程序服务器(例如JBoss AS)中的.jar集合进行部署,我试图弄清楚一套好的工具来管理依赖关系和生活 - 各种封装的周期。OSGi和...?我用什么来控制装载/卸载/重新装载包装?

我认为包装的如在(至少)三种可能的状态是:“卸载”,“未决”和“加载”,宽松地定义为如下:

  • 卸载:该包暂时不可用。
  • 待定:程序包本身可用,但不是所有的依赖项。因此,目前无法使用。
  • 加载:该软件包可用,并且其所有依赖项都满足。如果它是一个应用程序,它可以运行 - 如果它是一个库,它已准备好被另一个包使用。

(也可能有几个州,如“失败”对于试图加载,但没有一些其他原因比依赖不满意包等...)

在一包的生命周期,许多事情可能会导致包这三者之间改变状态:

  • 一个包,没有依赖加载,并且去从卸载加载
  • 一个包试图加载,但并非所有的依赖都满足;它从卸载待定
  • 包中的状态突然有其所有依赖关系满足(因为其他一些包去了状态加载),并自动开始加载本身;从转换到加载
  • 包被卸载。所有依赖于现在卸载的包的加载的包从加载等待
  • 程序包已更新为新版本。所有相关的软件包会自动重新加载,以访问更新的版本。

我已经开始使用OSGi定义的依赖关系的工作 - 它与我们的编译系统以及滚动和生产可靠的相关性信息。但是,如果我将两个OSGi软件包AB加载到JBoss中,其中B依赖于A,然后卸载A,看起来B看起来像愉快地继续运行。我明白,我可以用一些钩子来控制低级别的框架事件(框架事件),但是我的蜘蛛感觉是刺痛的,说必须有更好的方法来做到这一点

是否有一个很好的工具/框架/任何你想要调用它将赞扬OSGi在这些方面?

+1

将此输入为评论而非答案,因为问题中有很多移动部分,我没有时间全部回答。但是:卸载软件包不会影响从属软件包*,除非您执行刷新操作*。该刷新允许OSGi重新计算软件包线路,此时具有缺失相关性的软件包将变得无法解析。这种独立刷新的原因是解析代价昂贵,因此应该将一系列更新/安装/卸载组合在一起。 –

+1

至于更高层次的工具,我建议您阅读有关OSGi R5存储库和解析器规范。您应该专注于配置*组的捆绑,并且解析器规范可以帮助您计算出这些组的正确内容。您可以使用[Bndtools](http://bndtools.org)2.1版来试用解析器。 –

如果声明模块之间的依赖关系,则生命周期得到适当管理,并且在顶级模块停止之前必须停止子系统的解除扩展。

但是,停止模块只不过是将事件发送到捆绑激活器并从类加载器中移除引用。任何活动(例如线程或分布式实例)都必须手动清理。例如,您必须调用org.apache.commons.logging.LogFactory.release(ClassLoader)(如果使用公共日志记录)或删除任何注入的UI组件。

+0

当依赖被重新安装(也许是更新的版本)时,JBoss是否也会重新加载相关的bundle? –

+0

我正在构建基于Apache Felix(OSGi实现)的自定义服务器平台。 我想JBoss AS正在使用“平台”部署架构。在这种情况下,模块列表取决于存储库。如果从属捆绑包属于存储库,则必须在平台重新启动时重新启动它们。 – LoganMzz

在OSGi中,现有的类加载器将保持活动状态,直到您刷新框架。所以,如果你卸载B(其中A取决于B),那么A将继续在你刷新的时候继续搅动。您可以刷新整个框架或仅刷新受指定软件包影响的软件包(例如刷新B)。

刷新的目的是更新/卸载/安装一组软件包,然后在原子操作中应用更改。

+0

你如何调用刷新操作? –

+0

旧的(也是最常用的模型)是获取PackageAdmin服务,然后调用refreshPackages(null)(http://www.osgi.org/javadoc/r4v43/core/org/osgi/service/packageadmin/PackageAdmin .html#refreshPackages(org.osgi.framework.Bundle []))。但是,该服务已被弃用。所以新的方法是获取Bundle 0(context.getBundle(0)),然后调用adapt(FrameworkWiring.class)。生成的FrameworkWiring有一个refreshBundles方法。 –