在 SpringSource dm Server 中部署 GWT 應用程式 - 第二部分

工程 | Ben Corrie | 2008年11月24日 | ...

簡介

這是系列三篇部落格文章的第二篇,描述在 SpringSource dm Server™ 中建置和部署 GWT 應用程式的逐步方法。第一篇部落格文章探討了從範例 GWT 應用程式建立簡單 WAR 檔案的過程。這篇部落格文章將探討如何將我們在第一部分中建立的 WAR 檔案轉換為 「共用函式庫」 WAR。這表示我們將把應用程式的 GWT 相依性外部化到 OSGi 捆綁包中,以便它可以由任意數量的 GWT 應用程式共用。您可以將其視為使用 GWT 遠端處理功能擴展我們的 dm Server。

如同在第一部分中提到的,在這第二篇部落格文章中,我沒有使用 Spring Framework,而是專注於 SpringSource dm Server™SpringSource Tool Suite 來部署「純」GWT。

另請參閱第一部分,以了解 GWT StockWatcher 範例和我正在使用的軟體的背景資訊。

快速回顧

第一部分中,我們從頭開始以 Eclipse 專案建置了 GWT StockWatcher 範例應用程式,然後將程式碼產生到動態 Web 專案中,接著我們將其部署到 dm Server 中。最後,我們將動態 Web 專案匯出到 WAR 檔案,並在 STS 之外部署它。

此處描述的逐步方法將建立在我們在第一部分中所做的工作基礎之上,而不是重新開始。我們現在要變更的在第一部分中唯一做過的事情是移除對下列項目的明確相依性gwt-servlet.jar函式庫。

步驟 1:將我們的 GWT 相依性轉換為 OSGi 捆綁包

首先,稍微多一點背景資訊。「共用函式庫」方法的整體概念是在 dm Server 內使用 OSGi 捆綁包之間的明確匯入和匯出來建立相依性地圖。對於像我們的 StockWatcher 範例這樣的小型 WAR 檔案,這主要只是一個有趣的學術練習。然而,鑑於許多商業網路專案都以大型 WAR 檔案的形式發佈,這些檔案與數十甚至數百個相依的 jar 檔案打包在一起,將這些相依性分解為可共用的資源不僅從佔用空間的角度來看是有意義的,而且還使應用程式的封裝、版本控制和維護變得更加輕鬆。

好消息是,建立這些相依性的許多工作已經為您完成。SpringSource Enterprise Bundle Repository 包含大多數常見函式庫的「捆綁」版本。但是,在撰寫本文時,我們的 GWT 相依性是您必須自行轉換為捆綁包的函式庫範例。幸運的是,Eclipse 3.4 使這個過程非常簡單。

- 在專案瀏覽器中按一下滑鼠右鍵,然後選取「新增」->「其他」->「Plug-in Development」->「Plug-in from existing Jar archives」。- 按一下「Add external」並瀏覽至gwt-servlet.jar。- 按一下「下一步」,並將專案命名為「com.google.gwt」。- 設定外掛程式版本以反映 GWT 版本,在本例中為 1.5.3。- 選取「Analyze library contents and add dependencies」- 選取 Equinox OSGi 框架

按一下「完成」,不必切換到 Plug-in 開發視景。我們只是要再次直接匯出我們的捆綁包。

您現在應該會看到產生之MANIFEST.MF檔案的概觀,這是定義捆綁包相依性的位置。您會在「執行階段」標籤中看到,該工具已新增所有com.google.gwt..套件作為匯出。您還會在「相依性」標籤中看到,它已計算出此捆綁包需要一些javax.servlet..套件和一個junit套件。

我們現在將移除 JUnit 相依性,因為預設情況下它在 dm Server 中將無法解析。當然,如果我們願意,我們可以將 JUnit 捆綁包新增到 dm Server 以滿足相依性,或者我們可以透過新增以下內容使相依性成為選用的required:=optional。選取junit.framework套件,按一下「移除」,然後儲存。

值得指出的是,這是一種將 JAR 檔案轉換為捆綁包的粗略方法,並且不能保證在所有情況下都有效。首先,我們可能不希望匯出我們所有的套件。然而,更重要的是,存在一兩個原始碼層級的陷阱可能無法在 OSGi 中良好運作,例如使用Class.forName()。如有疑問,請始終先前往 SpringSource Enterprise Bundle Repository,而不是嘗試自行建立。

最後,我們需要將我們的 Plug-in 專案匯出為 OSGi 捆綁包。選取「匯出」->「Plug-in development」->「Deployable plug-ins and fragments」。選取一個方便的位置作為輸出目錄。

我們現在應該會在以下位置看到一個檔案<export path>/plugins/com.google.gwt_1.5.3.jar。下一步是重新命名檔案,使其與 dm Server 中其他具名捆綁包的格式一致:只需將底線變更為破折號com.google.gwt-1.5.3.jar。若未進行此變更,目前版本的 STS 將無法辨識捆綁包版本。如果您想跳過此步驟,可以從此處下載。

最後,將捆綁包複製到 dm Server 捆綁包儲存庫<dm Server installation root>/repository/bundles/usr。此處的任何捆綁包都可以是 dm Server 中其他捆綁包的相依性,但重要的是,它也將在 STS 中顯示為相依性,我們將在下一步中看到。

此時,您可以從工作區中刪除 com.google.gwt 專案,因為它已達到其目的。

步驟 2:將我們的 WAR 專案移轉到新的 OSGi 捆綁包

希望您現在應該有一個 dm Server 安裝,其中包含com.google.gwt-1.5.3.jar在其儲存庫中。

下一步是破壞我們的應用程式!

在 StockWatcherWar 上按一下滑鼠右鍵,選取「內容」->「Java EE Module Dependencies」,取消選取gwt-server.jar檔案,然後按一下「確定」。我們現在已移除 WAR 對 GWT 的明確相依性,並為自己造成了一些新問題,其中大多數是編譯器錯誤。

因此,我們需要將我們的動態 Web 專案轉換為 dm Server 捆綁包,以便它可以從我們新建立的 GWT 捆綁包中明確匯入它需要的相依性。若要執行此操作,請在 StockWatcherWar 上按一下滑鼠右鍵,然後選取「Spring Tools」->「Add OSGi Bundle Project Nature」。您應該會注意到專案現在帶有一個非常重要的「S」符號,且MANIFEST.MF也已變更字元

它已損壞,因為它看起來不像捆綁包資訊清單。讓我們新增一些合理的預設值 (您可以剪下並貼上以下內容,或使用標籤中的欄位)。請注意,您也可以在編輯器中使用 ctrl-space 來提示您有效的選項。

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: com.google.sample.stockwatcher Bundle-SymbolicName: com.google.sample.stockwatcher Bundle-Version: 1.0.0 Bundle-Description: Shared Libraries StockWatcher demo

因此,這已修正一個問題,即我們的捆綁包資訊清單現在看起來是合理的。但是,我們尚未定義對 GWT 捆綁包的相依性,因此我們仍然有一些編譯器錯誤。

選取「相依性」標籤,然後按一下「新增」。在最上方,您應該會看到 com.google.gwt 捆綁包神奇地出現。現在,重要的是要了解,此清單中出現的 GWT 捆綁包與我們在步驟 1 中建立的外掛程式專案無關。如果您從工作區中刪除該專案,捆綁包仍然會出現。它的運作原理是因為 dm Server 安裝設定為專案的執行階段,因此工具會在 dm Server 的儲存庫中尋找您可能想要匯入的任何捆綁包。如果這不起作用,則可能是 GWT 捆綁包未複製到正確的位置,或者 WAR 專案的執行階段未設定為 dm Server。在「內容」->「Targeted Runtimes」中檢查後者。

接下來,選取 GWT 捆綁包,按一下「確定」,然後儲存資訊清單。您現在應該會看到 GWT 捆綁包已新增至名為「Bundle Dependencies」的新類別路徑元素中

您現在應該會注意到大多數錯誤都已解決,但仍有一些錯誤尚未解決。這是因為我們的 GWT 捆綁包相依於javax.servletAPI,並且在我們擁有這些類別之前,類型階層是不完整的。

那麼,為什麼我們之前只有在gwt-servlet.jar在我們的建置路徑中時,沒有遇到這個問題?嗯,在我們進行變更之前,我們的 WAR 會擷取其建置路徑上的所有內容,其中包括 dm Server 目標執行階段提供的所有 JAR。但是,您可能已經注意到,當我們新增 OSGi Bundle Project Nature 時,建置路徑上的 dm Server JAR 消失了。這是因為,透過成為 OSGi 捆綁包,我們已進入一個不同的相依性世界,其中匯入和匯出必須明確宣告。

宣告我們對javax.servletAPI 的相依性,只需匯入另一個捆綁包即可。您會在清單中看到它為com.springsource.javax.servlet。新增兩個捆綁包後,儲存資訊清單,您現在應該會看到所有錯誤都已解決。呼!

如果我們現在導覽到 MANIFEST.MF 標籤,我們可以查看我們所有按鈕操作的效果:資訊清單中的綠色「Import-Bundle」項目。請注意,我們也可以在「Import-Bundle」之後輕鬆使用 ctrl-space,它會建議所有可能的匯入

如果您想查看我的專案,可以從此處下載壓縮副本。它包含執行階段組態,用於使用內嵌 Tomcat 在託管模式下啟動、使用 dm Server 在託管模式下啟動以及啟動 GWT 編譯器。請注意,使用內嵌 Tomcat 的託管模式可以正常運作,而無需修改捆綁包 WAR 專案。這是因為javax.servletdm Server 中的套件不再位於建置路徑中。若要使用我的專案,您需要GWT_ROOT_INSTALL變數,您可能需要選取您的 dm Server Target Runtime 執行個體,如第一部分中所述。

步驟 3:部署到 dm Server 上

部署我們的「共用函式庫」應用程式的步驟與第一部分中的步驟 7 和 8 完全相同,因此沒有必要再次詳細說明這些步驟。當然,主要的區別在於我們已成功將相依性分解為一個可以由多個 GWT 應用程式共用的函式庫。如果您下載我的 StockWatcher 共用函式庫 WAR,您會看到它現在是 290k 而不是 890k。

為了好玩,讓我們稍微了解一下內部運作,並查看我們的捆綁包如何互動。

當 dm Server 啟動時,它會通知您可以使用 telnet 用戶端存取其 OSGi 主控台

[2008-10-27 16:48:04.266] main                     <SPOF0001I> OSGi telnet 主控台可在連接埠 2401 上使用。

讓我們開啟終端機視窗,看看我們可以找到什麼

> telnet localhost 2401 Trying ::1... Connected to localhost. Escape character is '^]'.

osgi>

您可以透過輸入 help 來取得 Equinox 主控台可用的命令清單。還有一篇關於它的實用 DeveloperWorks 文章,您可以在此處閱讀。

輸入ss為我們提供所有正在執行的外掛程式的清單

osgi> ss

框架已啟動。

id    State       Bundle . . . . 73    ACTIVE      com.google.sample.stockwatcher_1.0.0 74    ACTIVE      com.google.gwt_1.5.3

輸入packages 74為我們提供 GWT 捆綁包中的所有匯出套件。它顯示 StockWatcherWar 捆綁包正在匯入所有匯出的套件。這是我們使用「Import-Bundle」的結果。事實證明,我們的 StockWatcherWar 實際需要的唯一套件是com.google.gwt.user.client.rpccom.google.gwt.user.server.rpc。如果我們願意,我們可以透過使用「Import-Package」明確匯入這些套件來更具選擇性。這在 dm Server Programmer Guide 中有描述。

file:////Users/bcorrie/dmServer-1.0.0/springsource-dm-server-1.0.0.RELEASE/work/com.springsource.server.deployer/Module/StockWatcherWar.war-0/StockWatcherWar.war [73] imports com.google.gwt.i18n.client.constants; version="0.0.0"<file:////Users/bcorrie/dmServer-1.0.0/springsource-dm-server-1.0.0.RELEASE/repository/bundles/usr/com.google.gwt-1.5.3.jar [74]>

步驟 4:在共用函式庫上部署其他 GWT 應用程式

值得注意的是,並非所有 GWT 應用程式都需要使用gwt-servlet.jar。只有使用某種形式遠端處理的 GWT 應用程式才相依於此函式庫。Google 在其發行版本中發佈了許多範例應用程式,其中大多數只產生 javascript 和 html,因此在部署時沒有 Java 程式碼。將這些範例轉換為 WAR 檔案很簡單,只需將 Compile 腳本執行到動態 Web 專案中,如第一部分步驟 5 中所述,然後建立適當的 web.xml。

然而,GWT 發行版本中包含的一個範例確實使用了一些簡單的遠端處理,稱為 DynaTable。使用這些部落格中描述的相同步驟和原則,我將此範例轉換為共用函式庫 WAR 檔案。若要查看我的做法,您可以下載壓縮的專案WAR 檔案並查看。這非常簡單地示範了在 dm Server 中執行多個應用程式的原則,這兩個應用程式都共用我們建立的 GWT 捆綁包。

期待第三部分

在本系列的最後一篇部落格文章中,我們將進一步模組化我們的 StockWatcher 範例,將其服務抽象化為可以熱插拔到執行中伺服器內外的捆綁包。

取得 Spring 電子報

隨時掌握 Spring 電子報的最新資訊

訂閱

領先一步

VMware 提供訓練和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部