JAR 包中替换依赖jar的正确姿势(Windows 环境)

一、问题背景

在 Spring Boot 项目中,Maven 打包时会将所有依赖整合成一个可执行 JAR,结构大致如下:

app.jar
├── BOOT-INF/
│ ├── classes/
│ └── lib/
│ ├── my-common-4.0-SNAPSHOT.jar
│ ├── spring-core-6.x.x.jar
│ └── ...
└── META-INF/

有时我们希望只替换其中的某个依赖 jar (比如 my-common-4.0-SNAPSHOT.jar),

结果直接用 WinRAR 或 7-Zip 替换后,启动时却报错:

复制代码
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/hz3000-pdec-common-4.0-SNAPSHOT.jar'. 
It has been compressed and nested jar files must be stored without compression.

二、问题原因

Spring Boot 的可执行 JAR(fat jar)中,
BOOT-INF/lib 下的所有依赖文件必须使用 存储模式(Stored) 保存,而非压缩模式(Deflated)。

📘 原理:

Spring Boot Loader 直接基于偏移量访问内部 JAR 文件,

若使用压缩模式,偏移量信息被破坏,导致无法解压读取。

而 WinRAR、7-Zip 等图形工具默认使用"压缩模式"

因此即使替换成功,运行时也会报错。

三、解决方案

mkdir D:\temp\BOOT-INF\lib

jar uf0 D:\app.jar -C D:\temp BOOT-INF/lib/my-common-4.0-SNAPSHOT.jar