在 OSGI 的 jetty 中部署 webapp

Deploy webapp in jetty in OSGI

我在发布这个问题之前搜索了很久,没有找到令人满意的答案,作为前提我想说我宁愿不使用框架来完成以下任务,我唯一的工具是 Felix, Jetty 和 Webapp。

我有一个使用 Maven 管理的 Web 应用程序,我将其部署在 OSGI 环境之外的 Jetty 中,但现在我也想将它部署在 OSGI 中,所以我面临着典型的 OSGI 问题和原则,下面是我明白了,如果我做错了请告诉我:

首先,回答您更高级别的 OSGi 问题:

  • I can leave maven "war" packaging

是的,但这意味着您正在生成一个 WAR 文件,并遵循所有规则。因此,您可能最终会在某个时候与 maven-war-plugin 战斗。

  • With apache.felix maven-bundle-plugin I create OSGI MANIFEST

我更喜欢使用 bnd-maven-plugin,但两者在幕后使用相同的库 (bnd)。生成 OSGi 清单(而不是手动编写)是迈向成功的非常重要的一步。

  • In OSGI there should be the jetty-bundle started before any "webapp bundle"

在编写良好的 OSGi 系统中,应该绝对没有启动顺序限制。在 Jetty 启动之前,您的 Web 应用程序将不可用,但哪个 bundle 先启动并不重要。

The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI bundles elsewhere

这取决于你。显然,要保持有效的 WAR 文件,classes 必须在 WEB-INF/classes 中。 OSGi 可以解决这个问题(尽管您需要设置 Bundle-Classpath),但这不是必需的。如果您想将它们放在 / 中,请继续。 OSGi 也支持嵌入式 JAR,但同样不是必需的。使用 / 作为 class 路径并使用 Import-Package 引用库是对 OSGi 更为惯用的用法。

OSGi 中的 Servlet

有一个支持网络应用程序的 OSGi 规范。它称为 Web 应用程序规范,是 OSGi 纲要规范的第 128 章。这是您可以从 OSGi 容器内部发布 servlet 的方法之一。但是,还有其他方法可以在 OSGi 中使用 Servlet。

如果您只想使用 WAR 文件完成所有操作,那么请直接跳过,因为我将告诉您一个替代方案,您可能会发现 easier/better.

如何在 OSGi 中部署 Servlet

在 OSGi 中部署 servlet 的最好和最简单的方法是使用 Http Whiteboard(OSGi 纲要第 140 章)。注册一个 servlet 非常简单,您只需将它发布为一个 OSGi 服务,并使用它应该匹配的模式。例如,当使用声明式服务时:

@Component(property="osgi.http.whiteboard.servlet.pattern=/foo")
public class MyServlet extends HttpServlet implements Servlet {
    ...
}

您还可以注册过滤器、监听器和各种其他东西。像这样使用声明式服务可以很容易地通过注入其他 OSGi 包提供的服务来与它们交互。

Apache Felix Http 服务很好,易于使用,它基于 Jetty 实现了此规范。

如何部署 Web 应用程序包

如果您真的想部署为 Web 应用程序包,则需要注意一些事项。

根据原始提交者的要求进行编辑

  1. 所有 servlet 的生命周期与 bundle 的生命周期完全相同,因此很难正确使用 OSGi 服务。在 Web Application Bundle 中,如果 servlet 所依赖的服务丢失或变得不可用,您将无法限制它的可见性。这可能会导致您依赖捆绑启动顺序,这很糟糕!
  2. 您必须在 OSGi 清单中设置额外的元数据,以确保 OSGi 可以处理 WAR 布局,并识别您的包以进行处理。
    • Bundle-ClassPath: WEB-INF/classes[ WEB-INF/lib/foo.jar]
    • Web 上下文路径:
  3. Jetty 不是(据我所知)OSGi Web 应用程序规范的实现。您将需要一个实现(可以是 Jetty 之上的 运行),例如 PAX-Web。
  4. OSGi Web 应用程序规范仅定义了对 Servlet 2.5 的支持(任何更高版本都是实现增值)。
  5. 许多人将 Web 应用程序包视为迁移路径,而不是最终目标。具有特殊的内部布局 (WEB-INF/classes) 并且通常遵循 "fat jar" 模型意味着 Web 应用程序包通常具有有限的模块化并且很难与其他工具一起使用。此外,与 OSGi Http 服务白板等模块化模式相比,它们无法与 OSGi 服务(见第 1 点)良好交互,这使得它们更难 write/maintain。这意味着一些人(包括我自己)将 Web 应用程序包视为 "first step" 迁移到 OSGi,最终使用 Http 服务白板。

根据您的 Maven 构建的设置方式,您可能会发现有必要对 bnd 使用 -wab 指令。这得到 bnd 将您的 classes 放入 WEB-INF/classes 并设置 Bundle-ClassPath