保護 Tomcat Web 應用程式

tomcat 會把 WAR 轉換成一個自我完備的 Tomcat 基礎目錄。它使用打包器內建的 Tomcat 元件,完全不會動到你本機安裝的 Tomcat。

1. GUI 操作

  1. 在應用程式類型頁面選擇 Tomcat WAR

    選擇 Tomcat WAR

  2. 選擇輸入 WAR、隨包 Java 版本與目標平臺,然後選擇簡單模式或進階模式。

    選擇輸入、Java 版本、目標平臺與模式

  3. 使用進階模式時,選擇 Tomcat 9 或 10.1,或維持自動偵測,並視需要設定上下文路徑、JVM 啟動選項與排除規則;簡單模式會依相容性掃描決定 Tomcat 版本。各選項的意義請參閱 Protector4J 進階模式設定

    設定 Tomcat 版本、上下文路徑與排除規則

  4. 選擇輸出目錄,核對參數摘要,然後點選執行保護

    選擇輸出目錄並執行保護

2. CLI 範例

指定上下文路徑:

p4j tomcat app.war dist --context /app

相容性掃描,以及自動套用掃描建議:

p4j tomcat app.war --compat-scan
p4j tomcat app.war dist --compat-apply --context /app

這兩個選項不能同時使用,差別如下:

選項作用何時使用
--compat-scan只掃描輸入 WAR,印出風險與設定建議後結束;不做編碼,也不產生 dist,因此不需要輸出目錄。初次保護應用程式、升級 Tomcat 相關相依套件、調整保護範圍或 JSP 設定之後,以及排查相容性問題時,先用它檢視報告。
--compat-apply掃描後合併保守建議,接著繼續編碼並寫出結果,因此必須指定輸出目錄。已經看過掃描結果並接受這些建議時,用它完成打包;規則驗證過之後的重複建置與 CI 流程也適用。

tomcat 而言,--compat-apply 可以依掃描結果追加排除規則,並調整 Tomcat 版本、掃描器 ZIP 覆蓋層與歸檔字尾這三類選項。對這三類選項,命令列中明確指定的值優先。建議排除的類別預設會與你明確寫的 --exclude 合併;若不希望自動追加,同時傳入 --no-compat-excludes 即可。掃描器只做靜態啟發式分析,需要修改程式碼才能解決的問題不會被 --compat-apply 自動修正,打包完成後仍然必須在目標平臺上做迴歸測試。

其他 CLI 命令、全部選項、環境變數與自動化範例,請參閱 CLI 參數參考

--tomcat-version 預設為 auto。需要明確指定時,設為 910.1

p4j tomcat app.war dist --context /app --tomcat-version 10.1

3. 輸出結構

dist/
├── bin/
│   ├── catalina.sh
│   ├── startup.sh
│   ├── shutdown.sh
│   └── *.bat
├── conf/p4jx/
│   ├── contexts.list
│   ├── protected-classes.list
│   └── allowed-prefixes.list
├── protected/
│   └── app.p4jx
├── lib/
│   ├── p4jx-tomcat-runtime.jar
│   └── tomcat-runtime-deps.jar
├── vlxjre/
├── run.sh
└── run.bat

預設不會產生實體 WAR。web.xml、靜態資源、未受保護的類別、中繼資料樁與受保護實作,全部位於 protected/<context>.p4jx 中,並透過 P4JX 的 WebResourceSet 呈現給 Tomcat。

4. 啟動與停止

前景執行:

./run.sh

以 Tomcat 的方式在背景啟動與停止:

./bin/startup.sh
./bin/shutdown.sh

Windows 使用對應的 .bat 檔案。記錄檔會寫入輸出目錄下的 logs/

打包 Windows 目標時,還可以額外產生一個原生啟動程式,用於在前景啟動內嵌的 Tomcat,詳見產生 Windows EXE 啟動器

JVM 啟動選項

打包時可以在 GUI 的 JVM 啟動選項中每行填寫一個選項,也可以在命令列中指定:

p4j tomcat app.war dist \
  --context /app \
  --jvm-option -Xms1g \
  --jvm-option -Xmx2g

若要在已部署的包中修改:

  • macOS 與 Linux:編輯 bin/catalina.sh,在 run_java() 內的 JVM_OPTS=(...) 之後加上 JVM_OPTS+=("-Xms1g" "-Xmx2g")。前景執行與由 startup.sh 發起的背景執行都會生效。
  • Windows 前景:編輯 bin\catalina.bat,在既有的 set "JVM_OPTS=..." 之後加上 set "JVM_OPTS=%JVM_OPTS% -Xms1g -Xmx2g"
  • Windows 背景:在 bin\startup.bat 呼叫 catalina.bat 之前,加上 set "APP_JAVA_OPTS=-Xms1g -Xmx2g"。如果需要一套同時涵蓋前景與背景的永久選項,直接用 GUI 或 CLI 重新產生會比較省事。

也可以在命令前設定 APP_JAVA_OPTS,只對這一次執行生效。完整的 CMD、PowerShell 與指令碼範例請見 JVM 啟動選項設定

5. Tomcat 版本的選擇

WAR 中使用的 API 命名空間Tomcat所需 Java
javax.servlet.*Tomcat 9Java 8、11、17、21 或 25
jakarta.servlet.*Tomcat 10.1Java 11、17、21 或 25

自動偵測會優先從應用程式類別與部署描述元中辨識 API 命名空間,JAR 檔案名稱只作為輔助佐證。如果 javaxjakarta 同時存在,工具會拒絕自動猜測。

6. JSP

WAR 中包含 JSP 時,預設會在編碼階段把它們預先編譯成 servlet 類別與 URL 對應。這是因為在執行時編譯 JSP 會從 Tomcat 工作目錄定義新類別,而這超出了受保護執行時所允許的類別定義邊界。

也可以明確控制:

--precompile-jsp
--no-precompile-jsp

正式環境請維持預設的預先編譯。關閉它可能導致含 JSP 的應用程式打不開頁面。

7. 保護範圍與排除規則

預設保護 WEB-INF/classes 下的應用程式類別,WEB-INF/lib 不在保護範圍內。面向 Web 的類別可以排除:

p4j tomcat app.war dist \
  --context /app \
  --exclude 'com.example.web.**,com.example.dto.**'

優先排除 servlet、filter、listener,以及 DTO、設定類別、實體、JNI 橋接類別,還有需要由容器增強的類別。相容性掃描會給出保守建議。

8. 在同一個 Tomcat 包中追加應用程式

p4j tomcat second.war dist \
  --append-app \
  --context /second

限制條件:

  • 上下文路徑不能與既有應用程式衝突;
  • 新舊應用程式必須使用相同的 Tomcat 主版本、Java 版本與目標平臺;
  • 未傳入 --append-app 時,工具會拒絕寫入既有的 Tomcat 包;
  • 在 GUI 中勾選將應用追加到現有 Tomcat 資料夾,並直接選擇既有目錄。

9. Java 8 注意事項

Java 8 目標會自動啟用 ZIP 覆蓋層,使 Tomcat 的 WebResourceSet 能夠開啟受保護歸檔。