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 應用所需的額外包匯入。這次,該應用成功啟動,並可以透過網路瀏覽器訪問:https://: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 社群中即將舉行的所有活動。

檢視全部