部署 WAR 到 IBM Bluemix 與 Tomcat 上面的執行結果(Context Root)不同原因

其實拿 IBM Bluemix 上面的 WebSphere Liberty Profile 和 Apache Tomcat 相比,是有一點拿雞腿比XX的味道了(誤)。
不過既然資策會的同學問了,我就誠心誠意的來解答吧!

其實拿 IBM Bluemix 上面的 WebSphere Liberty Profile 和 Apache Tomcat 相比,是有一點拿雞腿比XX的味道了(誤)。
不過既然資策會的同學問了,我就誠心誠意的來解答吧!

WebSphere Liberty Profile 是完整的 JavaEE 認證過的平台(原廠說明可以 看此 );而 Apache Tomcat 僅有「實做」了 JavaEE 標準中的幾個部分:Java Servlet、JavaServer Pages、Java Expression Language 和 Java WebSocket,真正符合 JavaEE Web Profile 認證的 Apache 軟體,則是 Apache TomEE

所以在 WebSphere Liberty Profile 上跑出和 Apache Tomcat 上不同的結果,其實是蠻常見的事情,不需要太訝異。
在工作上也常常遇到人家這樣問我:「Tomcat 上可以跑,為什麼放到 WebSphere 不行!一定是 WebSphere 有問題!」。
其實這樣的說法就好像你去考一個模擬考出來,說你可以考上這個考試,然後到了正式測驗的時候卻沒有考過,再反過來質疑正式測驗的內容是不是有問題的道理是相同的。

好,廢話不多說,就讓我們來看看在 IBM Bluemix WebSphere Liberty Profile 和 Apache Tomcat 上面,為何相同的 WAR 會跑出不同的結果。

確認 IBM  Bluemix  是否已經配置完成、 Tomcat  是否已經配置完成(在這邊使用  Tomcat8 ,最主要因素是  Tomcat8  所使用的  JavaEE  規格與目前  IBM Bluemix  上面的  WebSphere Liberty Profile  相同)。

6B0B13F7-CA30-4141-BAF1-A349CC8E60C5

建立一個  Dynamic Web Project ,名稱為  javaeedemo2 (名稱可以調整,但不要和  IBM Bluemix  上面的相同即可,在上圖中已經有一個名稱為 javaeedemo 的應用程式了),而且注意不要加入到任何的 EAR 裡面。

71E8989C-5C54-46C2-A857-664145E19FF6

8ECB4703-F558-4D3F-88F2-B167A4210C91

原則上,這個被建立出來的  Dynamic Web Project ,它的  context root  會是  project name ,也就是  javaeedemo2 。怎麼確認?可以在 project 建立完成之後選擇  project ,按下滑鼠右鍵,選擇「 properties 」,再選擇「 Web Project Settings 」,就可以看到 context root 設定了。

6BB4136E-F22D-4502-A164-4F9AA90075D8

17F24BE3-993C-485E-A97F-87FA62F9265D

將這個  javaeedemo2 Dynamic Web Project 掛到  IBM Bluemix  上面去執行。

0BFFE8EF-5076-466F-87D5-50456862C05E

1F3CAB49-D5B5-429B-9096-667EC5F17884

7A4F6D0D-EFA6-4F73-ABB9-406ECC33E212

BF24FFB5-F8BA-4CED-AB64-C33381003F99

243BFEFB-CE5E-49D0-9D48-F038E4E3ECD2

看完這幾個畫面,如果你又曾經在  Tomcat  上面這樣跑過  Dynamic Web Project  的話,應該大概有感覺這兩者最主要的差別在哪裡:
以 IBM Bluemix 來說,javaeedemo2 被掛在一個 sub-domain 執行,因此透過這樣的部署方式部署上去的 Dynamic Web Project,它在 Eclipse 的 context root 設定會失效,IBM Bluemix 預設會把這個 Dynamic Web Project 的 context root 自動綁定在 / 底下。
加一個 HTML 檔案上去執行看看。

DE79C60E-F7EB-42B2-A097-B0F72E6E3CE1

6E0621BC-5E5E-4F20-A043-1720194DBBE9

9A846992-C60C-40CF-9D90-61F136EE6693

B462D26E-C3B6-490D-85BD-221ADFE5B974

7795F84E-463B-40C7-A0B1-5812E1141C5E

07D08E34-34E0-4E89-953E-39991EB4D6C4

F76C2115-5B6E-4C1E-ADD7-2B66C878CAE3

從最後一張圖就可以看出結果與前面的假設相同,IBM Bluemix 會將 Dynamic Web Project 以 / 的 context root 進行部署;這樣的情況,又要怎麼改變呢?
嘗試著在 Eclipse 裡面調整 context root, 選擇 javaeedemo2 這個  project ,按下滑鼠右鍵,選擇「 properties 」,再選擇「 Web Project Settings 」 。
可以看到是 context root 是 javaeedemo2。

22BE3FCE-ECD5-4593-AB76-CBDE7B013CDE

改成 javaeedemo3 看看。

80085723-7BDB-423B-9ACF-4C4D5464F417

重新部署。

8112E87A-196F-45E3-82E1-A7C8AA450B53

再執行看看 index.html。

D363E120-F7D7-47DA-878C-55E0D0501685

顯示 404 錯誤,代表在這個網址找不到這張 HTML。
把網址換成 http://javaeedemo2.mybluemix.net/javaeedemo3/index.html 看看,可以看到正常的結果。

D2C18952-6EB8-4A8C-9EFE-9C6A1958C89B

換到 Apache Tomcat 執行看看,很直覺的就是使用 Eclipse 專案的 context root 去跑了:

1AF59A09-3B55-4A42-80F1-1DD85E5BAF99

0D664840-527B-4B11-B820-66E3182872A7

3EB7A923-C751-45B4-AE0C-150D9479D199

F063BE1E-3CEF-446B-901D-38070CFA2939

9F79FB8D-4833-447B-9FEA-CC76A810F04C

6D8F1C5A-3BE8-42C2-8CB5-BCB82688F445

走到這邊,大概可以歸納出以下幾點:
當我們在 Eclipse 建立新的 Dynamic Web Project,並且將這個 WAR 部署到 IBM Bluemix WebSphere Liberty Profile 的時候,IBM Bluemix 在一開始可能會忽略我們指定的 context root,而將這個 WAR 放在 / 根目錄執行。

我們可以透過修改 Dynamic Web Project 的設定,將 context root 做修改並且重新部署之後,IBM Bluemix WebSphere Liberty Profile 就會接受新的 context root。

這是 IBM Bluemix WebSphere Liberty Profile 的特性,並不是 IBM WebSphere Liberty Profile 的特性,在雲平台上面還是有些許的不同(會以指定 sub-domain 的方式優先)。

在 JavaEE certified 的平台上面跑應用程式,概念上還是建議具備 EAR(Enterprise application ARchive)的概念比較好,不要只有 WAR(Web application ARchive)的概念。

資策會同學來信最主要是問 context root 的問題(因為他們使用了絕對路徑的方式在處理網址或是 form 的 action 屬性),而好的作法應該是用相對路徑去處理這些事情。

因為,在 JavaEE 的標準裡面,負責部署應用程式的管理者,是有機會修改你 WAR(Web application Archive)的 context root 的,所以非必要盡量不要在任何地方使用絕對路徑。

Mark Su

熱愛籃球、程式設計與美食。

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.

Most discussed