內容

目錄

一般

請先閱讀一般 遷移指南頁面,了解適用於 Apache Tomcat® 版本間遷移或升級的常見考量。

從 7.0.x 遷移到 8.0.x

此區段列出已知的 7.0.x 和 8.0.x 之間所有變更,這些變更可能會在升級時造成向下相容性問題。

需要 Java 7

Apache Tomcat 8.0.x 需要 Java 7 或更新版本。Apache Tomcat 7.0.x 需要 Java 6。

規格 API

Apache Tomcat 8 支援 Java Servlet 3.1、JavaServer Pages 2.3、Java Unified Expression Language 3.0 和 Java API for WebSocket 1.1 規格。各規格版本間的變更可以在各規格文件中的變更附錄中找到。

Servlet 3.1 API

在使用萬用字元匯入語法的 JSP 頁面中,Servlet API 中新增的類別可能會與 Web 應用程式中的類別衝突。例如,如果套件 "a" 包含類別 ReadListener,下列 JSP 頁面將無法在 Tomcat 8 中編譯

<%@page import="a.*"%>
<% ReadListener listener = new ReadListener(); %>

這是因為隱式匯入 javax.servlet.* 和明確匯入 a.* 會提供 Servlet 3.1 中新增的類別 ReadListener 的衝突定義。解決方法是使用明確匯入,import="a.ReadListener"

JavaServer Pages 2.3

統一表達式語言 3.0 新增了對靜態欄位和方法的參照支援。在 JSP 中支援此功能需要變更 javax.servlet.jsp.el.ScopedAttributeELResolver 實作,以便它也能檢查識別碼,看看它們是否為已匯入類別或欄位的名稱。在某些情況下,此變更會觸發明顯的變慢。這會影響可能參照頁面、要求、工作階段或應用程式範圍變數的識別碼,或可能是未定義的。當未定義時,解析識別碼會花費更長的時間,因為現在它也會檢查它是否為已匯入類別或欄位。為避免這種變慢,例如

${undefined}

應以

${requestScope.undefined}

或類似的取代,使用變數定義的適當範圍。

Jar 掃描

在實作 Servlet 3.1 的過程中,在 Tomcat 7 的 Servlet 3.0 可插入性實作中識別出許多錯誤。特別是

  • SCI 掃描未遵守類別載入器順序;
  • 容器 JAR 中的片段已處理,而不是忽略;
  • 有時會忽略容器提供的 SCI。

這些問題已針對 Tomcat 8 修正,但未回溯移植到 Tomcat 7,因為修正需要對 JarScanner 元件進行重大 API 變更,以及對組態選項進行變更。

在移轉到 Tomcat 8 時,需要檢閱 Jar 掃描組態,並針對新的組態選項進行調整,而且需要更新自訂 JarScanner 實作,以實作新的 API。

預設連接器實作

預設的 HTTP 和 AJP 連接器實作已從 Java 阻擋式 IO 實作 (BIO) 切換到 Java 非阻擋式 IO 實作 (NIO)。仍然可以使用 BIO,但使用非阻擋式 IO 的 Servlet 3.1 和 WebSocket 1.0 功能將改用阻擋式 IO,這可能會導致意外的應用程式行為。

預設 URL 編碼

HTTP 和 AJP 連接器的 URIEncoding 屬性的預設值已從「ISO-8859-1」變更為「UTF-8」(如果「嚴格 servlet 相容性」模式關閉,這是預設值)。此設定指定用於解碼請求 URI 路徑和查詢中「%xx」編碼位元的字元編碼。

如果伺服器組態為「嚴格 servlet 相容性」開啟,連接器的 URIEncoding 屬性的預設值為「ISO-8859-1」,與舊版 Tomcat 相同。

參考:HTTP 連接器AJP 連接器

領域

已將摘要密碼的處理移至新的 CredentialHandler 元件。相關的 Realm 屬性在 8.0.x 中仍可使用,但已標示為過時,並已在 Tomcat 8.5.x 中移除。

Web 應用程式資源

別名、虛擬載入器、虛擬目錄內容、JAR 資源和外部儲存庫功能都提供一種方式來將資源新增到 Web 應用程式,已替換為單一架構,而不是分別實作(這變得越來越難以維護)。資源 文件提供有關如何使用新實作的詳細資訊。

資源的重構也導致從預設 Context 實作 (org.apache.catalina.core.StandardContext) 中移除多個屬性。現在可以透過 Web 應用程式使用的 資源 實作來設定下列屬性

  • allowLinking
  • cachingAllowed
  • cacheMaxSize
  • cacheObjectMaxSize
  • cacheTtl(已重新命名:在 Tomcat 7 中為 cacheTTL)

例如,Tomcat 7 和 Tomcat 8 中的設定

<!-- Tomcat 7: -->
<Context allowLinking="true" />

<!-- Tomcat 8: -->
<Context>
  <Resources allowLinking="true" />
</Context>

資料庫連線池

Tomcat 8 和 Tomcat 7 都附帶兩個資料庫連線池實作。第一個實作(預設實作;雖然技術上可以透過 javax.sql.DataSource.Factory 系統屬性來變更)是 Apache Commons DBCP 2.x 專案的副本,已重新命名為不同的套件。第二個實作 是 Tomcat JDBC 連線池,一個獨立的專案。

Apache Commons DBCP 1.x(Tomcat 7 及更早版本使用)和 Apache Commons DBCP 2.x 之間有許多顯著的變更,可能會需要變更設定。

  • maxActive 設定選項已重新命名為 maxTotal
  • maxWait 設定選項已重新命名為 maxWaitMillis
  • JDBC 驅動程式 JAR 可以放置在 WEB-INF/lib 中,作為 $CATALINA_BASE/lib 的替代方案,前提是只有該 Web 應用程式使用驅動程式類別。
  • 連線驗證不再需要驗證查詢和至少一個 testXxx 屬性設定為 true。如果未定義驗證查詢,且至少一個 testxxx 屬性為 true,將使用 Connection.isValid() 來驗證連線。
  • removeAbandoned 設定選項已由 removeAbandonedOnBorrowremoveAbandonedOnMaintenance 取代。

此外,Commons DBCP 已新增多個新的設定選項。應檢閱這些選項以確定應使用哪些選項(如果有)。

請注意,如果您使用 Tomcat JDBC 連線池(或任何第三方資料庫連線池實作),則不需要上述變更。

叢集

Servlet 3.1 中新增了 HttpServletRequest.changeSessionId() 方法,使得 org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener 變得不再必要,因此已將其移除。升級到 Tomcat 8 時,必須從叢集設定中移除它。

偵錯

當使用 jpda 選項啟動 Tomcat 以啟用遠端偵錯時,Tomcat 8 預設會在 localhost:8000 上監聽。較早的版本會在 *:8000 上監聽。如有需要,可以在 setenv.[bat|sh] 等檔案中設定 JPDA_ADDRESS 環境變數來覆寫此預設值。

內部 API

儘管 Tomcat 8 內部 API 與 Tomcat 7 廣泛相容,但已在詳細層級進行許多變更,且它們並非二進位相容。與 Tomcat 內部元件互動的客製元件開發人員應檢閱相關 API 的 JavaDoc。

特別要注意的是

  • Manager、Loader 和 Resources 已從 Container 移至 Context,因為 Context 是唯一使用它們的地方。
  • Mapper 已從 Connector 移至 Service,因為 Mapper 對特定 Service 的所有 Connector 都是相同的。
  • 新的 Resources 實作將別名、VirtualLoader、VirtualDirContext、JAR 資源和外部儲存庫合併到單一架構中,而不是為每個功能提供一個獨立的架構。
  • 已新增一個新的介面 SessionIdGenerator,使會話 ID 產生具有可擴充性。已新增方法到 Manager 介面中,以取得和設定 ID 產生器類別名稱。

部署

將 Web 應用程式部署為 WAR 檔案,且將 Tomcat 設定為不解壓縮 WAR,將導致啟動時間和執行時間效能大幅下降。已測量出啟動時間變慢了三到十倍。執行時間影響將顯著取決於應用程式結構。

強烈建議不要在 Host 上設定 unpackWARs="false" 或在 Context 上設定 unpackWAR="false"。以下是停用解壓縮的常見原因,以及 Tomcat 8 的建議替代方案

  • 安全性(appBase 對 Tomcat 使用者為唯讀) - 部署(作為不同的使用者)一個已解壓縮的目錄到 appBase,而不是 WAR 檔案。
  • 在多個主機之間共用 appBase - 將 WAR 檔案部署到共用位置,然後使用 context.xml 檔案視需要將 Web 應用程式新增到主機。請注意,在任何情況下都強烈不建議在多個主機之間共用 appBase。
  • 離線部署 - 從 Tomcat 8.0.21 開始,當 WAR 在 Tomcat 未執行時已更新,Tomcat 會偵測到,並在下一次啟動時移除過期的已展開目錄,並部署已更新的 WAR 檔案,因此只要使用 unpackWAR="true",並在 Tomcat 未執行時繼續部署 WAR 即可。

升級 8.0.x

當將 Apache Tomcat 的執行個體從 Tomcat 8 的一個版本升級到另一個版本時,特別是在為 $CATALINA_HOME 和 $CATALINA_BASE 使用個別位置時,有必要確保設定檔中的任何變更(例如新的屬性和預設值的變更)已套用為升級的一部分。為了協助識別這些變更,可以透過以下表單檢視 Tomcat 8 不同版本中的設定檔差異。

Tomcat 8.0.x 重要變更

Tomcat 開發人員的目標是讓每個修補程式版本都與前一個版本完全向後相容。偶爾,為了修復錯誤,有必要中斷向後相容性。在多數情況下,這些變更將不會被注意到。本節列出未完全向後相容的變更,且在升級時可能會導致中斷。

  • 從 8.0.24 開始,連接器上 maxPostSize 屬性的值 0 的意義已變更為表示零限制,而非沒有限制,以與 maxSavePostSize 保持一致,並更直觀。

    參考:HTTP 連接器AJP 連接器

Tomcat 8.0.x 組態檔差異

從下列方塊中選取組態檔案、舊版本和新版本,然後按一下「檢視差異」以查看差異。差異將顯示在新分頁/視窗中。

您也可以使用類似下列的 Subversion 指令(全部在一行中)

svn diff
  --old=http://svn.apache.org/repos/asf/tomcat/archive/tc8.0.x/tags/TOMCAT_8_0_1/conf/
  --new=http://svn.apache.org/repos/asf/tomcat/archive/tc8.0.x/tags/TOMCAT_8_0_3/conf/