🧩【超新手也看得懂】修改 JAR 裡的 properties 並重新打包:一步一步教你(含三種做法+避坑清單)
- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
TL;DR(一句話版本)
*.jar
就是壓縮檔(像 zip)。想改設定,只要把修改後的
cploader.properties
放回 JAR 原本的位置再存檔即可;或乾脆把設定放到 JAR
外面啟動時覆蓋,之後改設定就不用重打包。
這篇會解決什麼?
-
同資料夾出現兩個設定檔(例如
cploader.properties與cploader2.properties)到底差在哪、會不會互相影響? -
我只想修改設定檔,不用重編譯程式可以嗎?
-
重新打包成
.jar的三種方法(JDKjar指令、7-Zip 覆蓋、外部覆蓋免打包) -
用 Eclipse / Maven / Gradle 重新產生 JAR 的步驟
-
常見地雷(簽章失效、路徑錯放、編碼亂碼、classpath 順序衝突)
先搞懂兩件事
1) 什麼是 JAR?
JAR(Java ARchive)= 把
.class、圖片、設定檔(像
*.properties)壓成一包的
zip。你可以用解壓工具打開它。
2) 什麼是
properties?
*.properties
是純文字的鍵值設定檔,例如:
input.dir = D:\\data\\incoming success.log = D:\\logs\\success.txt file.pattern = _CP_.*\\.std
Java 程式啟動時讀它,決定去哪裡找檔、輸出到哪裡、檔名規則怎麼配對等。
同資料夾兩個
properties
檔代表什麼?會互相影響嗎?
-
常見情境:
-
cploader.properties:預設設定。 -
cploader2.properties或.bak:另一套配置(例如另一環境 / 備份)。
-
-
是否生效:完全取決於程式碼載入哪一個檔名。
-
如果程式碼固定讀
cploader.properties,那cploader2.properties只是放著,不會生效。 -
若程式碼支援啟動參數(如
-Dconfig=cploader2.properties),才會改讀第二份。
-
-
同時讀兩份的專案很少見;若真的兩份都載入,後讀的值會覆蓋先讀的值。
快速判斷誰被用到:把其中一份的某個關鍵值改成明顯錯的(例如把
file.pattern
改成
_NEVER_MATCH_),立刻執行一次。行為有變就表示程式讀到它。
我要改
cploader.properties,最簡單的三種做法
一定先備份原 JAR!(隨便 copy 一份就好)
方法 A:用 JDK 的
jar
指令(最穩、可控)
前提:你知道
cploader.properties
在 JAR 的路徑(通常在根目錄)。
Windows 範例
REM 1) 備份 copy C:\apps\myapp\app.jar C:\apps\myapp\app.backup.jar REM 2) 更新 JAR 內同名檔案(把 C:\edit\cploader.properties 放回 JAR 根目錄) "%JAVA_HOME%\bin\jar.exe" uf C:\apps\myapp\app.jar -C C:\edit cploader.properties REM 3) 驗證 JAR 內確實有那個檔 "%JAVA_HOME%\bin\jar.exe" tf C:\apps\myapp\app.jar | findstr /i cploader.properties
macOS / Linux 範例
# 1) 備份
cp /opt/myapp/app.jar /opt/myapp/app.backup.jar
# 2) 更新 JAR 內檔案
$JAVA_HOME/bin/jar uf /opt/myapp/app.jar -C /home/user/edit cploader.properties
# 3) 驗證
$JAVA_HOME/bin/jar tf /opt/myapp/app.jar | grep -i cploader.properties
-C <資料夾> 檔名
的寫法能避免把本機完整路徑包進 JAR,確保檔案回到原本那層。
方法 B:用 7-Zip / WinRAR 直接拖拉覆蓋(最直覺)
-
以 7-Zip 打開
app.jar(就當成 zip)。 -
把改好的
cploader.properties拖進視窗並覆蓋(注意:路徑要跟原來一致)。 -
關閉視窗、執行測試。
方法 C:不改 JAR,外部覆蓋(之後改設定免打包)
如果主程式用類別載入器讀
classpath 裡的
cploader.properties,你可以把外部資料夾放在 classpath 前面,讓外部檔案「蓋掉」JAR 內建:
REM 先讀 C:\config 的 properties,再讀 app.jar 內容 REM ※ 這種方式要知道 Main-Class,不能用 -jar(-jar 會忽略 -cp) java -cp C:\config;C:\apps\myapp\app.jar com.example.Main
優點:日後只改
C:\config\cploader.properties
就好、不用重打包。
缺點:要用
-cp 啟動、要知道
Main-Class(看
META-INF/MANIFEST.MF)。
想要「正式」重產 JAR?(Eclipse / Maven / Gradle)
方案 1:Eclipse(無建構工具)
-
建一個
src/main/resources(右鍵專案 → New → Source Folder),把cploader.properties放進去。 -
Project → Clean。 -
右鍵專案 →
Export… → Java → Runnable JAR file。-
選你的啟動組態(有
main的那個)。 -
Library handling 建議選「Package required libraries into generated JAR」產生單一可執行 JAR。
-
-
產出後
java -jar測試。
方案 2:Maven
src/main/resources/cploader.properties
→
mvn clean package -DskipTests
需要 fat-jar 就加
shade-plugin。pom.xml(簡化示例):
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.bak</exclude>
</excludes>
</resource>
</resources>
</build>
方案 3:Gradle
src/main/resources/cploader.properties
→
./gradlew clean shadowJar
build.gradle(簡化示例):
plugins { id 'application' id 'com.github.johnrengelman.shadow' version '8.1.1' } application { mainClass = 'com.example.Main' } tasks.processResources { exclude '**/*.bak' }
常見地雷 & 檢查清單
-
簽章失效:JAR 內若有
META-INF/*.SF、*.RSA、*.DSA,你任何改動都可能讓驗章失敗。-
企業環境通常要求簽章;你可能需要
jarsigner重新簽。 -
若應用程式不檢查簽章,也可移除舊簽章檔(視政策而定)。
-
-
放錯路徑:一定要把
cploader.properties放回它在 JAR 裡原本的層級(常見是根目錄)。-
檢查方式:
jar tf app.jar | findstr /i cploader.properties
-
-
編碼:
*.properties建議用 UTF-8(無 BOM)。中文或特殊符號用錯編碼會顯示亂碼或解析失敗。 -
重複檔案:同一個 classpath 上如果有兩份
cploader.properties,誰先被讀取取決於 classpath 順序。-
盡量只保留 一份生效版本;或採用「外部覆蓋」並清楚紀錄啟動腳本。
-
-
如何知道 Main-Class?
-
jar tf app.jar找META-INF/MANIFEST.MF,打開看Main-Class: com.example.Main。
-
最佳實務(建議長期做法)
-
外部化設定:啟動時讀外部路徑(例如環境變數或
-Dconfig=...),JAR 內只留一份「預設」。 -
啟動時列印生效設定:log 出「實際載入的檔名與關鍵 key 值」,日後追查超省時間。
-
環境分流:命名清楚(如
cploader-dev.properties、cploader-prod.properties)+ 啟動參數切換。 -
備份與版本管理:把
properties納入 Git 版控(敏感值可放.env或 CI/CD 變數)。
FAQ
Q1:我只有改
properties,需要重新編譯程式碼嗎?
A:不需要。它是純資源檔,直接更新 JAR 即可。
Q2:改完 JAR 之後程式說簽章錯誤?
A:你改動破壞了簽章。請用
jarsigner
重新簽,或依公司政策移除簽章檔並改用未簽章流程(不建議)。
Q3:如何快速確認程式到底讀到哪一份設定?
A:在程式啟動時 log 出 key 值;或暫時把某個值改成明顯錯誤(例如
file.pattern
無法匹配),看行為是否改變。
小抄(命令速查)
更新 JAR 內的
cploader.properties(Windows)
copy C:\apps\myapp\app.jar C:\apps\myapp\app.backup.jar "%JAVA_HOME%\bin\jar.exe" uf C:\apps\myapp\app.jar -C C:\edit cploader.properties "%JAVA_HOME%\bin\jar.exe" tf C:\apps\myapp\app.jar | findstr /i cploader.properties
用外部覆蓋啟動(知道 Main-Class 時)
java -cp C:\config;C:\apps\myapp\app.jar com.example.Main
結語
對初學者來說,「修改 JAR
裡的設定」聽起來很可怕,但其實就是換掉壓縮檔中的一張文字檔。選擇你最順手的方式(jar
指令、7-Zip、或外部覆蓋),再配上上面的避坑清單,就能穩定又可控地完成修改。需要進一步把流程「產品化」時,再導入
Maven/Gradle 與啟動參數,把設定管理做得更清楚就好。祝順利!
留言
張貼留言