科技 · 實用指南
遇到 UnsupportedClassVersionError?改 Java 前先證明類別檔與載入 JVM
錯誤已指出相容性不符的兩端。先保留類別檔主版本、產物與真實啟動器,再決定升級 runtime 或重新設定建置目標,清除陳舊輸出,並在本機、CI 與類生產入口驗證同一產物。

錯誤已指出相容性不符的兩端。先保留類別檔主版本、產物與真實啟動器,再決定升級 runtime 或重新設定建置目標,清除陳舊輸出,並在本機、CI 與類生產入口驗證同一產物。
JVM 只能載入支援的類別檔版本;較高主版本會在應用程式碼執行前被拒絕。 Java 8 到 Java 25 分別對應類別檔主版本 52 到 69。
1. 凍結精確的不符證據
複製第一筆完整 UnsupportedClassVersionError,包括被拒絕類別、回報的類別檔版本、runtime 最大識別版本、啟動命令與時間。必須在失敗環境記錄 java -version 與 javac -version,不可改用之後開啟的另一個 shell。
以 JVM 規範換算兩個主版本,但不要停在版本表。一般主版本不符與次版本 65535 的 preview 不符要求不同;只要錯誤或 javap 顯示,就同時記錄主、次版本。
2. 識別被拒絕的產物
定位第一個 stack frame 點名的精確 .class 或 JAR,記錄路徑、雜湊、套件座標或 image digest 與建置來源。可行時對抽出的類別執行 javap -verbose,不執行程式碼即可確認主版本。
判斷被拒絕類別屬於應用、建置 plugin、annotation processor、IDE helper 或傳遞相依。改應用目標無法重新編譯已發布為新版 bytecode 的第三方 plugin。
3. 證明實際載入 runtime
追蹤真正載入類別的 process,記錄解析後 java 路徑、命令列、JAVA_HOME 或 toolchain 來源、工作目錄與容器 image。服務查 unit 或 supervisor,CI 查 runner step,IDE 與 daemon 重啟後再核設定。
不要把登入 shell 的 which java 當證明。wrapper、SDK manager、symlink、daemon 重用、PATH 順序與容器層都可能在 shell 看似正確時選另一個 JVM。
4. 只選一個相容方向
若應用需要新版 bytecode 且相依支援,就在責任啟動器升級載入 runtime 並確認支援週期。修改服務、CI image、IDE 或容器,不只改開發 shell,並重啟持久 daemon。
若必須保留舊 runtime,就用 --release 或工具等價設定重新指定可控程式碼,並選擇發布相容 bytecode 的相依或 plugin。不要修改類別檔 header,也不要把 source 相容當 runtime 相容。
5. 清除陳舊與混合輸出
刪除或隔離保留新版類別的編譯輸出、cache 與套件。以選定 toolchain 乾淨建置,記錄產物雜湊,並檢查代表性的應用類別、生成類別與相依類別。
多模組混合輸出很常見:某個模組、生成任務或 plugin 仍可能使用另一 JDK。必須證明建置 log、toolchain 選擇與最終套件,不能只看 compile 成功。
6. 驗證每個真實入口
讓同一產物雜湊通過相關 shell、IDE 或建置工具、CI、服務與類生產容器。要求第一個類別可載入、預期測試通過,且沒有後續不相容類別。
保存驗收表:啟動器、java 路徑、runtime 版本、產物雜湊、類別主版本、結果與 rollback。只有同一套相容政策控制建置與載入端才算完成,本機一次成功不算結案。
