在 Wildfly 中用于模块间服务注入的 OSGI 替代方案是啥?

Posted

技术标签:

【中文标题】在 Wildfly 中用于模块间服务注入的 OSGI 替代方案是啥?【英文标题】:What is the alternative to OSGI for inter-module service injection in Wildfly?在 Wildfly 中用于模块间服务注入的 OSGI 替代方案是什么? 【发布时间】:2013-07-26 10:54:22 【问题描述】:

我们正在解开一个经典的传统单片 EAR 打包 Java EE 应用程序。我们(最复杂的)组件布线模式如下:组件 A“需要”接口 X,而组件 B 和 C (... N) 各自“提供”接口 X。我们的要求是打包和部署 A、B、C和 X 分开独立,以最大限度地减少停机时间并最大限度地减少业务影响。

因此,我们需要必要的稳健性,以允许在运行时删除和添加(重新部署)接口的提供者(B,C),而不需要重新部署接口的消费者(A),也不需要重新启动服务器。该解决方案将在 Wildfly 8 上运行,但只要在 Wildfly 8 上运行,就可以使用其他技术。

我们已经使用 JBoss-OSGI 和 Weld-OSGI 实现了一个 POC,它满足了我们的所有要求,并为我们提供了一个极好的迁移路径。然而,在 Wildfly 8 Alpha 3 中,JBoss-OSGI 已从默认发行版中删除。这让我们认为我们应该探索更符合 Wildfly 背后人们的想法的替代方案。

因此,问题是,在 Wildfly 8 上,有什么替代 OSGI 的模块间服务注入可以满足我们的要求?

为了预算、简单性、性能开销和公司政策,我们不得不取消以下内容: 1。远程 EJB 2。网页服务 3。 JSON/休息 4。 SCA

请注意,这不是要求就 OSGI 的可行性进行辩论,也不是对不同解决方案进行评估或比较。我只是在寻找任何符合我们标准且不基于 OSGI 的解决方案。

【问题讨论】:

我很感激你不想辩论,你说得对,*** 不是辩论的地方。但是……您说 JBoss-OSGi 满足了您的所有要求,并提供了一个极好的迁移路径。需要明确的是,JBoss-OSGi 仍然可用并受到 Red Hat 的支持,尽管现在它是一个可选的附加组件,而不是开箱即用的。所以我真的不明白这个问题的动机。 有效点。是的,JBoss-OSGI 仍然可以作为附加组件使用。但是,Red Hat 的支持是一个更棘手的问题,不包括在 EAP 等之外,这是我首先关心的问题。此外,当 Wildfly 背后的重要人物并没有真正购买它时,在 Wildfly 上使用 JBoss-OSGI 是有风险的。再一次,我不想争论他们观点的有效性,但它存在的事实是使用 JBoss-OSGI 的风险。最后,我觉得我错过了他们为这样的场景实际想到的更明显的解决方案,而且我倾向于用 OSGI 概念思考可能让我对此视而不见。 嘿@ArjanTijms,你真的巡视整个 *** 以确保人们说“Java EE”而不是广泛理解的术语 JEE 和 J2EE?您对命名法和商标的投入令人钦佩,但有点狭隘……我的意思是为什么不将 OSGI 更正为 OSGi? 我想我理解你的推理,虽然我不同意。虽然 Red Hat 的一些人不购买 OSGi,但其他人肯定购买。从核心产品中删除 OSGi 似乎是由一个派系成功推动的,但我相信他们将很难杀死 JBoss-OSGi 附加项目。无论如何...你是客户,Red Hat 不应该关心支持你想做的事情,而不是你试图猜测他们认为你“应该”做什么? @NeilBartlett 感谢您的评论,是的,我确实尝试过。请注意,SO 本身也将 JEE 和 J2EE 重命名为 Java EE(参见 ***.com/tags/synonyms,过滤例如 JEE)。另请参阅此答案:***.com/questions/17762084/…您对 OSGi 等的看法是正确的。如果我碰巧在同一个句子中发现它们,我偶尔也会尝试改进它们,但我每天只编辑几分钟,不幸的是,在那段时间我只能做这么多。 【参考方案1】:

既然您询问的是 WildFly 背后的人的想法,我将向您推荐以下邮件列表消息。它由 David Lloyd 发布到 Jigsaw 开发列表中,他(我相信)是 WildFly 所基于的 JBoss Modules 的设计师。上下文是关于在 Jigsaw 中引入服务模型的讨论:http://mail.openjdk.java.net/pipermail/jigsaw-dev/2012-February/002161.html

David 似乎在说服务本身的理念 存在缺陷——即您不需要它们! – 或者 Java 6 中引入的 ServiceLoader API 已经充分解决了该要求。

但是,众所周知,ServiceLoader 不适用于使用类加载器隔离的模块系统,其中包括 OSGi 和 JBoss 模块。这是因为 ServiceLoader 使用类路径扫描,并且在模块系统中没有“类路径”。在 OSGi 中,我们已经指定了一种适配 ServiceLoader 的方法(尽管它很糟糕并且需要字节码转换)。也许 JBoss Modules 也有处理这个问题的方法,但我通过快速扫描他们的文档找不到任何东西。

无论如何,正如我在上面的评论中所说,我对你的动机感到困惑。您显然可以从 OSGi 提供的服务模型中受益,而且 JBoss-OSGi 仍然可用并受到 Red Hat 的支持……那么为什么不继续使用它呢?特别是如果 WildFly 开箱即用并没有明确提供任何您想要的东西。

【讨论】:

非常相关的链接,它澄清了很多。我可以看到 David Lloyd 的发展方向,但在我们的案例中,我实际上认为可以提出一个很好的论据来支持服务理念。并不是说我有那种奢侈,因为它是一个遗留应用程序。请参阅上面关于我的动机的评论。 您能否支持关于红帽仍然可用并支持 jboss-osgi 的说法?据我所知(而且我很长一段时间以来一直在思考这个问题,也得到了 RH 的支持)它从未得到 Red Hat 的支持,只有社区的努力,并且如今甚至没有。此外,它不适用于任何最终版本的 Wildfly(请参阅 this 和 this)OOB,并且负责集成的人员 (Thomas Diesler) 不再是 Red Hat 的员工。 好的,我刚刚注意到这条消息是在 2013 年写的。当时至少有一个想法是支持 JBoss-OSGi,所以这个答案可能在这方面已经过时了。跨度> 【参考方案2】:

Apache Felix 可以作为“OSGI 主机”嵌入到您的应用服务器中。然后您可以为所需的系统创建插件机制。您的所有服务都可以实现为“捆绑”。服务器中的 OSGI 主机可以在部署文件夹中找到捆绑包,并安装/启动它们。然后,您可以在不重新启动应用程序服务器的情况下启用您的 web 服务、rest 和其他服务。

【讨论】:

虽然 Felix 确实是 JBoss-OSGI 的替代品,而且您的解决方案可以很好地工作,但它并不能让我们远离 OSGI。请记住,在这方面,我们正试图将我们的想法与 Wildfly 8 世界保持一致,一个没有 OSGI 的世界。 Wildfly 的 jboss-modules 基础架构提供了许多与 OSGI 相似的功能,因此必须可以在不实际使用 OSGI 的情况下实现某种类似 OSGI 的解决方案。不过,我会把你的建议放在我的待办事项清单上...... '没有 OSGI 的世界'。 Apache Felix 为您提供 osgi 功能,而不是 WildFly。然后您可以使用 IPojo 或等...但是您也想摆脱 OSGI 解决方案,而不仅仅是因为 WildFly 的限制? 正确。请参阅我对 Neil Bartlett 评论的回复以了解我的推理。【参考方案3】:

在我工作的地方,当 JBoss-OSGi 为 declared dead 时,我们必须选择一些东西才能继续项目。我们采用了 JBoss Modules + EJB 方法,因为它们实际上得到了 Red Hat 的支持。 JBoss Modules 用于静态模块依赖,EJB 用于运行时注入服务。

我们不使用远程 EJB,而是使用 EJB 3.x 本地 EJB,并且您的列表中没有丢弃它,所以我想提供这个是可以的。

【讨论】:

这确实解决了模块间注入的需求,但据我所知,当您注入EJB的接口时,您必须指定实现。这意味着您创建了对特定实现的静态依赖——在我的问题中是 B 或 C。 Neil 提到的 OSGi 和 Java ServiceLoader 框架都提供了一种方法来提供接口的多种实现,并且只在运行时决定使用哪一个。 @AmpieBarnard 嗯。不,您不必指定实现。这就是重点。我们有很多单一接口的实现,您可以更改运行时。 我很难过。请您附上一些代码,其中您有相同接口 X 的两个 EJB 实现(B 和 C),将接口注入 EJB A,部署两个实现,然后在运行时决定使用哪个实现? 我手头没有这样的例子,那是为我的雇主完成的工作。但我看不出需要从哪里指定实现 - EJB 通常基于具有商定名称空间的 JNDI 查找,而不是对实现进行硬编码。 除非指定实现是指指定 JNDI 名称?应该使用可移植的 JNDI 命名空间,而不是与实现类绑定的东西......

以上是关于在 Wildfly 中用于模块间服务注入的 OSGI 替代方案是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Shiro / CDI 注入安全主体适用于 Glassfish 但不适用于 Wildfly

在 JBoss/WildFly 中注入 EntityManager

从 Wildfly 10 中排除所有模块

在 WildFly 中配置/注入 JMS 连接工厂和主题

NestJS 在非模块文件中注入模块服务

无法在使用 Arquillian 和 WildFly 的 JPA 集成测试中注入 EntityManager