首先,回答您更高级别的 OSGi 问题:
是的,但这意味着您正在生成一个 WAR 文件,其中包含以下所有规则。因此,您最终可能会在某个时候与maven-war-plugin 抗争。
- 使用 apache.felix maven-bundle-plugin 创建 OSGI MANIFEST
我更喜欢使用bnd-maven-plugin,但两者都使用相同的库(bnd)。生成 OSGi 清单(而不是手动编写)是迈向成功的非常重要的一步。
- 在 OSGI 中,应该在任何“webapp bundle”之前启动 jetty-bundle
在编写良好的 OSGi 系统中,绝对没有启动顺序限制。在 Jetty 启动之前,您的 Web 应用程序将不可用,但哪个包先启动并不重要。
webapp bundle 会有它的 WEB-INF/classes,但是,真正的 OSGI 风格,它不会有任何 WEB-INF/lib,因为它会在其他地方找到它的依赖作为 OSGI 包
这取决于你。显然,要保持有效的 WAR 文件,类必须位于 WEB-INF/classes 中。 OSGi 可以解决这个问题(尽管您需要设置Bundle-Classpath),但这不是必需的。如果您想将它们放在/ 中,请继续。 OSGi 也支持嵌入式 JAR,但同样不是必需的。使用/ 作为类路径并使用Import-Package 引用库是OSGi 更惯用的用法。
OSGi 中的 Servlet
有一个支持 Web 应用程序的 OSGi 规范。它被称为 Web 应用程序规范,它是 OSGi 纲要规范的第 128 章。这是您可以从 OSGi 容器内部发布 servlet 的方法之一。然而,在 OSGi 中还有其他使用 Servlet 的方法。
如果您只想使用 WAR 文件完成所有操作,请跳过,因为我将告诉您一个替代方案,您可能会发现它更容易/更好。
如何在 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 应用程序包,那么需要注意一些事项。
根据原始提交者的要求进行编辑
- 所有 servlet 的生命周期与 bundle 的生命周期完全相同,因此很难正确使用 OSGi 服务。在 Web 应用程序包中,如果 servlet 所依赖的服务丢失或不可用,您将无法限制其可见性。这可能会导致您依赖捆绑启动顺序,这很糟糕!
- 您必须在您的 OSGi 清单中设置额外的元数据,以确保 OSGi 可以处理 WAR 布局,并识别您的包进行处理。
- Bundle-ClassPath:WEB-INF/classes[, WEB-INF/lib/foo.jar]
- Web 上下文路径:
- Jetty 不是(据我所知)OSGi Web 应用程序规范的实现。您将需要一个实现(可以在 Jetty 上运行),例如 PAX-Web。
- OSGi Web 应用程序规范只定义了对 Servlet 2.5 的支持(任何更高的版本都是实现增值)。
- 许多人将 Web 应用程序包视为迁移路径,而不是最终目标。具有特殊的内部布局 (
WEB-INF/classes) 并且通常遵循“胖 jar”模型意味着 Web 应用程序包通常具有有限的模块化,并且很难与其他工具一起使用。此外,它们无法与 OSGi 服务进行良好交互(参见第 1 点),这使得它们比诸如 OSGi Http 服务白板等模块化模式更难编写/维护。这意味着一些人(包括我自己)将 Web 应用程序包视为迁移到 OSGi 的“第一步”,最终使用 Http 服务白板。
根据您的 Maven 构建的设置方式,您可能会发现有必要对 bnd 使用 -wab 指令。这让 bnd 将您的课程放入 WEB-INF/classes 并设置 Bundle-ClassPath