相容性與保護範圍

P4JX 會加密儲存受保護類別的方法實作,並且只允許隨包的 VLX JRE 在執行時讀取。為了在保護強度與框架相容性之間取得平衡,建議只保護核心商業邏輯,把框架進入點、DTO 與實體、需要由框架在執行時動態產生或修改的類別,以及第三方相依套件排除在保護範圍之外。

1. 先執行相容性掃描

只掃描,不產生輸出:

p4j javaapp app.jar --compat-scan
p4j springboot app.jar --compat-scan
p4j tomcat app.war --compat-scan

掃描並套用保守建議:

p4j springboot app.jar dist --compat-apply

你明確指定的選項,優先權一律高於自動建議。掃描屬於靜態啟發式分析:報告中出現「需要複查」,不代表應用程式一定會出問題;報告沒有發現問題,也不能取代在目標平臺上的迴歸測試。

掃描結果要求修改程式碼時

如果 GUI 報告顯示需要處理(英文介面為 ACTION REQUIRED),表示必須修改應用程式原始碼,這類問題無法靠調整打包參數解決。報告會列出涉及的具體類別與方法,並給出以下其中一類建議:

  • 從記憶體讀取 ZIP 或 JAR:把 ByteArrayInputStream 改成以檔案為基礎的讀取方式,例如 Files.newInputStream(Path)FileInputStreamZipFileJarFile
  • 從原始位元組定義類別:不要對受保護的類別直接呼叫 ClassLoader#defineClass,改用 Class.forName()ClassLoader.loadClass(),讓 P4JX 執行時完成類別載入。

修改原始碼後重新建置 JAR 或 WAR,再執行一次相容性掃描;確認報告中不再出現該問題,才產生保護包。

2. 建議的保護模型

公開邊界/框架進入點 → 一般 facade 或介面 → 受保護的核心實作

範例:

--protect 'com.example.service.impl.**' \
--exclude 'com.example.dto.**,com.example.config.**'

3. 通常不應保護的類別

  • 控制器、Servlet、Filter、Listener、Advice;
  • Spring 設定類別,以及經 AOT 或 CGLIB 增強的物件;
  • Jackson DTO、record、JPA 實體、序列化模型;
  • JNI、SWT 等原生橋接類別;
  • 由 Agent、ORM、Mock 框架、熱重載或自訂 ClassLoader 改寫或重新定義的類別;
  • 第三方框架與開放原始碼相依套件;
  • 需要讀取自身真實 class 位元組碼的類別。

4. 不支援或受限的 JVM 能力

執行環境

  • 受保護的應用程式必須使用隨包的 VLX JRE 執行;
  • 不支援 JPMS 的 -m 啟動方式,也不支援單一原始檔啟動;
  • 類別路徑上的一般 JAR 必須由打包器登錄,不能在部署時任意追加;
  • 不要用 VLX JRE 去執行未受保護的一般應用程式。

除錯與 Agent

  • 不支援 JVMTI、JDWP 除錯器、效能分析器、覆蓋率工具,以及多數 APM agent;
  • 不支援 -javaagent-agentlib、熱重載與類別重新定義;
  • 需要位元組碼織入的處理,必須在編碼之前完成。

啟動最佳化

  • 不支援 CDS、AppCDS 與 AOT;
  • ZGC 與 Shenandoah GC 不在 P4JX 執行時的支援範圍內。

5. 類別資源與掃描器

讀取受保護類別的 .class 資源時,得到的是中繼資料樁:類別名稱、簽章與註解都會保留,但不含真實的方法主體。

  • 一般反射可以讀到中繼資料,但無法還原原始位元組碼;
  • 自行解析實體 ZIP 的工具,預設看不到 P4JX 歸檔中的內容,可以嘗試 --zip-overlay scanner
  • ClassGraph、Reflections 這類類別路徑掃描器,在 Spring Boot 下可能需要搭配 --layout fat
  • 不支援以 ZipInputStreamJarInputStream 從記憶體串流、網路串流中解析 P4JX 歸檔;
  • zipfs 檢視是唯讀的,無法透過它修改歸檔。

6. 歸檔行為

  • .jar 字尾並不代表它是一般 JAR,內容仍然是 P4JX;
  • Multi-Release JAR 會在編碼時依目標 Java 版本攤平;
  • 原 JAR 的簽章與憑證語意不會保留,如果散布環節有要求,請對最終交付物另行簽章;
  • 不要修改、重新壓縮或合併產生的 P4JX 檔案。