OSGi Web Container 简介

工程 | Rob Harrop | 2009 年 5 月 27 日 | ...

更新: 添加了 Git 版本控制说明。

在过去的几个月里,我一直与 Subbarao Meduri、Graham Charters、Hal Hildebrand 以及来自 OSGi Enterprise Expert Group 的其他人一起致力于 RFC66 Web Container 规范。Web Container 规范定义了如何在 OSGi 服务平台上以标准方式部署 WAR 文件。

这对我们来说非常有趣,因为 dm Server 支持 WAR 文件已经近 18 个月了,我们很高兴能够朝着标准模型努力。作为最终用户,您将能够在 OSGi 上部署 WAR 文件,而无需依赖专有 API 或功能。

SpringSource 负责编写 Web Container 参考实现,我在过去几周一直在为此努力。在这篇博客中,我将描述 Web Container 规范的主要特性,并讨论开始使用 RI 代码所需的步骤。我不被允许发布规范文档,但我会概述最重要的几点。

目前,RI 没有二进制分发版,但从源代码构建非常容易上手。

Web Container 的主要特性

Web Container 支持的最有趣的特性包括:

  • WAR 文件的安装
  • Web 应用 Bundle (WAB) 的安装
  • 使用扩展器控制 Web 应用生命周期
  • 使用 URL 参数控制配置属性

安装 WAR 文件

对我来说,Web Container 最令人兴奋的特性是能够直接将 WAR 文件部署到 OSGi 中,*而无需更改您的代码*。(使用 JNDI 的 WAR 文件需要修改代码才能使用,因为 JNDI 目前不是规范的一部分。正在进行工作来解决这个问题,所以我预计这个限制不会永远存在。)

要将 WAR 文件安装到 OSGi 中,只需在调用 BundleContext.installBundle 或使用平台控制台时,在文件位置前加上 webbundle:。例如,在 Equinox 中,我可以这样做:

install webbundle:file:formtags.war

当然,这要求您的 OSGi 平台中安装了 Web Container 实现。

Web Container 会对 WAR 执行各种转换,以确保它具有符号名称、版本以及正常工作所需的必要导入。Web Container 还会更新 Bundle 类路径,以添加 WEB-INF/classesWEB-INF/lib 中的每个 JAR 文件。

安装 Web 应用 Bundle (WAB)

如果您不想依赖 Web Container 转换您的 WAR 文件,则可以完全绕过转换阶段。只需自己添加适当的 Manifest 头,然后直接安装 Bundle,省略 webbundle 协议即可。

WAB 的 Bundle 类路径上不能有任何不在 WEB-INF 下的条目。这是为了防止您的任何应用类作为资源在 Web 应用中可见。WAB 可能还会出现其他限制,但这些尚未最终确定。

使用扩展器控制生命周期

Web Container 使用 扩展器模型 来控制 Web 应用生命周期。Web 应用在其对应的 Bundle 启动时启动,并在该 Bundle 停止时停止。

在 Equinox 中,这意味着我可以直接从控制台启动和停止我的 Web 应用。例如,如果上面的 formtags.war Bundle 的 Bundle ID 是 50

start 50 ... Tomcat 输出 ... stop 50

使用 URL 参数控制配置

可以通过在安装 URL 后附加某些支持的配置属性来控制 WAR 文件配置。

例如,要控制 Web 应用的上下文路径,可以添加 Web-ContextPath 选项

install webbundle:file:formtags.war?Web-ContextPath=ftags

或者控制生成的 Bundle-SymbolicName 头

install webbundle:file:formtags.war?Bundle-SymbolicName=ftags.bundle

Web Container 和 dm Server

Web Container RI 中的代码主要来自并受到 dm Server 中代码的启发,然而,RI 需要完整的 dm Server。我们将用 Web Container RI 替换 dm Server 中当前的 Web 代码,并且还将采用 Web Container 作为在 OSGi 上构建 Web 应用的推荐方法。

参考实现简介

Web Container RI 使用 Tomcat 作为 Servlet 容器实现。RI 本身由四个 Bundle 组成。core Bundle 包含所有与 Servlet 容器无关的代码。tomcat Bundle 包含特定于 Tomcat 的代码。tomcat.fragment Bundle 包含默认的 Tomcat 配置,并作为 Fragment 附加到 Tomcat Catalina Bundle。如果您倾向于手动管理 Web 应用生命周期,可以删除包含所有扩展器行为的 extender Bundle。

构建参考实现

要运行 RI,您需要从源代码构建它。源代码可以直接从 Git 获取:

git clone git://git.springsource.org/osgi-web-container/osgi-web-container.git

代码检出后,您可以使用以下命令构建和测试它:

cd build-web-container ant clean test collect

如果测试失败,请提交 JIRA。成功构建后,您可以运行 Web Container 并安装一些 WAR 文件。

运行参考实现

我正在使用 PAX Runner 来运行 Web Container RI。我的 PAX Runner 配置使用构建好的二进制文件和 Ivy 管理的依赖项来运行 Web Container。

build-web-container 目录下,您会找到一个名为 runner.bundles 的文件。此文件可用于指示 PAX Runner 安装 Web Container 所需的所有 Bundle:

pax-run --platform=equinox --snapshot runner.bundles

此命令使用 PAX Runner 启动 Equinox。--snapshot 标志告诉 PAX Runner 下载 Equinox 最新的稳定版本——该版本实现了已知的最新 OSGi 4.2 规范。

Equinox 启动后,输入 ss 命令验证 Bundle 是否已安装,您应该会看到大约 45 个 Bundle 已安装并正在运行。

安装应用

我正在使用 dm Server 的 FormTags WAR 示例进行测试。您可以从 此处 下载。

如果我直接安装 FormTags 应用,事情并未完全按预期进行:

install webbundle:file:formtags.war Bundle id is 48 start 48

运行 start 后,我收到一个错误,抱怨 org.xml.sax 包中某个类的 ClassNotFoundException。这里的问题在于 WAR 文件默认只获得 4 个导入:javax.servletjavax.servlet.httpjavax.servlet.jspjavax.servlet.tagext

使用 Import-Package URL 参数解决这个问题相对容易:

uninstall 48 install webbundle:file:/Users/robharrop/tmp/formtags.war?Import-Package=org.xml.sax,org.xml.sax.helpers,javax.xml.parsers,org.w3c.dom Bundle id is 49 start 49

这里我指定了 FormTags 应用所需的额外包导入。这次,该应用成功启动,并可以通过网络浏览器访问:http://localhost:8080/formtags

在 dm Server 中,WAR 文件会导入系统 Bundle 导出的每个包,这意味着常见的系统类型会自动可用。我认为这是一个有用的特性,我很想知道您是否同意,或者您是否更喜欢手动控制对系统包的访问。

下一步是什么?

Web Container 规范仍在不断发展,我正在努力保持 RI 同步。我正在着手将 dm Server 迁移到使用 Web Container RI 来替代其自身的 Web 支持,在接下来的几周内我会对此有更多介绍。

获取 Spring 快讯

订阅 Spring 快讯,保持连接

订阅

抢占先机

VMware 提供培训和认证,助您飞速发展。

了解更多

获取支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一次简单订阅即可获得。

了解更多

即将举行的活动

查看 Spring 社区中即将举行的所有活动。

查看全部