🔧【完整教學】如何替換 JAR 檔中的 class?新手也能懂的兩種方法(免重編譯)

 

📌 前言:為什麼需要「直接替換 JAR 裡的 class」?

在實務開發中,你可能會遇到這種情境:

  • 客戶系統已經在跑,無法重新部署整個專案
  • 只需要修正一個小 bug(例如匯出邏輯錯誤)
  • 沒有完整原始碼或 build 環境(Maven / Gradle)

這時候,「直接替換 JAR 裡的 class」就會是一個**快速救火(Hotfix)**的技巧。


🧠 先理解一件事:JAR 是什麼?

JAR(Java Archive)其實就是一個「壓縮檔」,概念上就像:

📦 ZIP 檔 + Java 專用結構

裡面通常會長這樣:

BOOT-INF/
  classes/
    (你的 class 檔)
  lib/
    (依賴套件)
META-INF/

所以你可以把它想成:

👉「一個可以被 Java 執行的壓縮資料夾」


🚀 方法一:用壓縮工具直接替換(最簡單推薦)

這是最適合新手的方式 👍

🪜 步驟教學

① 備份 JAR(非常重要)

example-app.jar → example-app_backup.jar

② 用壓縮工具打開 JAR

用以下任一工具:

  • 7-Zip
  • WinRAR
  • Bandizip

右鍵 → 開啟壓縮檔


③ 找到 class 位置

依照 JAR 裡的結構找到目標檔案,例如:

BOOT-INF/classes/.../YourService.class

④ 拖入新的 class 覆蓋

  1. 打開你新的 .class 檔所在資料夾
  2. 拖曳進壓縮檔視窗
  3. 選擇「覆蓋」

⑤ 存檔並測試

直接重新執行 JAR:

java -jar example-app.jar

⚙️ 方法二:用指令更新(進階工程師用)

這種方式適合你熟悉命令列的情況。


❗ 前提條件

你需要:

  • ✅ JDK(不是 JRE)
  • ❌ JRE 是沒有工具的(這是很多人會踩的坑)

🪜 概念流程

  1. 建立一個資料夾,模擬 JAR 內部結構
  2. 把新的 .class 放進正確位置
  3. 用指令「更新」JAR

📁 結構範例

temp_folder/
  BOOT-INF/
    classes/
      .../YourService.class

🔄 更新指令

jar -update -file example-app.jar 路徑/YourService.class

👉 這個動作本質就是:

用你提供的 class,覆蓋 JAR 裡同路徑的檔案


⚠️ 常見錯誤(90%的人會踩)

❌ 1. 找不到 jar 指令

原因:

👉 你用的是「JRE」不是「JDK」

解法:

  • 安裝 JDK
  • 或改用壓縮工具(推薦)

❌ 2. 路徑不一致

錯誤:

JAR 裡:BOOT-INF/classes/a/b/c.class
你放:a/b/c.class ❌

👉 一定要完全一樣!


❌ 3. Java 版本不相容

例如:

  • 原系統是 Java 8
  • 你用 Java 17 編譯 class

會出現:

Unsupported class version error

❌ 4. Spring Boot 特殊結構

Spring Boot JAR 裡 class 都在:

BOOT-INF/classes/

👉 千萬不要放錯層!


💡 什麼時候適合用這招?

✔ 緊急修 bug
✔ 無法重新部署
✔ 小範圍修改


🚫 什麼時候不要用?

❌ 大改功能
❌ 多個 class 變動
❌ 有 CI/CD 的專案

👉 正確做法應該是重新 build


🧑‍💻 工程師觀點總結

如果用一句話講這件事:

🔥「直接替換 JAR class,就是用最快速度修 production bug 的偏門技巧」

但同時也要記住:

⚠️「它不是長期解法,只是臨時救火」


📌 結語

這篇教學幫你解決了三個核心問題:

  • JAR 是什麼
  • 為什麼可以直接改 class
  • 怎麼安全地替換

如果你是正在維護系統的工程師,這招你一定會用到。

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🖥️遠端桌面連線完整新手指南:Windows RDP、Chrome Remote Desktop、AnyDesk、TeamViewer 一次搞懂

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)