Java 奥斯基和。。。?我用什么来控制包裹的装载/卸载/重新装载?

Java 奥斯基和。。。?我用什么来控制包裹的装载/卸载/重新装载?,java,osgi,Java,Osgi,我有一个庞大的应用程序和库生态系统,这些应用程序和库目前作为.jar的集合部署在各种应用程序服务器(例如JBoss as)中,我正试图找到一套好的工具来管理各种包的依赖关系和生命周期 我认为包处于(至少)三种可能的状态之一:“已卸载”、“待处理”和“已加载”,大致定义如下: 已卸载:该软件包目前不可用 挂起:包本身可用,但并非所有依赖项都可用。因此,目前无法使用 已加载:该包可用,并且满足其所有依赖项。如果它是一个应用程序,它可以运行——如果它是一个库,它可以被另一个包使用 (可能还有一些状

我有一个庞大的应用程序和库生态系统,这些应用程序和库目前作为.jar的集合部署在各种应用程序服务器(例如JBoss as)中,我正试图找到一套好的工具来管理各种包的依赖关系和生命周期

我认为包处于(至少)三种可能的状态之一:“已卸载”、“待处理”和“已加载”,大致定义如下:

  • 已卸载:该软件包目前不可用
  • 挂起:包本身可用,但并非所有依赖项都可用。因此,目前无法使用
  • 已加载:该包可用,并且满足其所有依赖项。如果它是一个应用程序,它可以运行——如果它是一个库,它可以被另一个包使用
(可能还有一些状态,例如,对于尝试加载但由于依赖关系不满足以外的其他原因失败的包,“失败”等等。)

在包的生命周期中,许多事情可能会导致包在以下三种情况之间更改状态:

  • 加载一个没有依赖项的包,并从卸载到加载
  • 包尝试加载,但并非所有依赖项都满足;它从卸载到挂起
  • 处于挂起状态的包突然满足了它的所有依赖项(因为其他一些包进入加载状态),并自动开始加载自己;从挂起到加载的转换
  • 一个包被卸载。依赖于现在卸载的包的所有已加载包都从已加载变为挂起
  • 软件包将更新为较新的版本。所有相关软件包都会自动重新加载,以访问更新版本
我已经开始使用OSGi定义依赖关系——它与我们的构建系统配合得很好,并生成可靠的依赖关系信息。但是,如果我将两个OSGi捆绑包
A
B
加载到JBoss中,
B
依赖于
A
,然后卸载
A
,那么
B
似乎一直在愉快地运行。我知道我可以使用一些钩子在低级别(框架事件)上控制它,但我的蜘蛛感觉很刺痛,说一定有更好的方法来做到这一点


是否有一个很好的工具/框架/无论你想叫它什么,都可以在这些方面对OSGi进行补充?

如果你声明模块之间的依赖性,那么生命周期将得到正确管理,并且在停止顶级模块之前必须停止子代的依赖性


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

在OSGi中,现有类加载器将保持活动状态,直到您刷新框架。所以,如果你卸载了B(A依赖于B),那么A将继续搅拌直到你刷新。您可以刷新整个框架,也可以只刷新受给定捆绑包影响的捆绑包(例如refresh B)

刷新的目的是更新/卸载/安装一组捆绑包,然后在“原子”操作中应用更改

旧的(也是最常用的模型)是获取PackageAdmin服务,然后对其调用
refreshPackages(null)
(osgi.org/javadoc/r4v43/core/org/osgi/service/PackageAdmin/…)。 但是,此服务已弃用。因此,目前的做法是:

 FrameworkWiring fw = context
     .getBundle(0)
     .adapt(FrameworkWiring.class);
 fw.refreshBundles(null);

更新了

在重新安装依赖项时,JBoss是否也会重新加载依赖项捆绑包(可能是在更新的版本中)?我正在使用构建在ApacheFelix(OSGi实现)之上的定制服务器平台。我想JBossAS使用的是“平台”部署架构。在这种情况下,模块列表取决于存储库。如果从属捆绑包属于存储库,则必须在平台重新启动时重新启动。请将其作为注释而不是答案输入,因为问题中有许多活动部分,我没有时间完整回答。但是:在执行刷新操作之前,卸载捆绑不会影响从属捆绑。刷新允许OSGi重新计算包布线,此时缺少依赖项的包将无法解析。这个单独的刷新操作的原因是解析非常昂贵,因此一系列更新/安装/卸载应该一起批处理。至于更高级别的工具,我建议您阅读OSGi R5存储库和解析程序规范。您应该专注于提供捆绑包组,而解析器规范可以帮助您确定这些组的正确内容。您可以使用版本2.1试用解析程序。如何调用刷新操作?旧的(也是最常用的模型)是获取PackageAdmin服务,然后对其调用refreshPackages(null)()。但是,此服务已弃用。因此,新方法是获取Bundle 0(context.getBundle(0)),然后对其调用adapt(frameworkwilling.class)。生成的FrameworkWiring具有refreshBundles方法。