CentOS下更新Spring Boot可执行jar包内文件时内容被清空求助
问题原因
Spring Boot 开启executable=true配置后打包生成的可执行jar并非标准jar/zip格式:Spring Boot Maven插件会在标准jar包的文件头部拼接一段shell启动脚本,用于支持直接以./xxx.jar的方式运行。
- 标准
jar命令的-u更新参数仅支持识别标准jar格式,无法识别带前导启动脚本的可执行jar,会误将目标文件当作新的空jar包进行覆盖写入,因此原有内容全部丢失,仅保留你新增的文件。 - 原生
zip命令同样严格校验zip文件头结构,前导的shell脚本破坏了标准zip结构,因此会抛出文件结构无效的报错。 - 7z工具会扫描整个文件寻找zip签名段,忽略前面的冗余脚本内容,因此可以正常识别并更新文件。
CentOS环境解决方案
方案1:使用p7zip(最简便,和Windows7z操作一致)
CentOS源中提供了7z的命令行版本p7zip,安装后直接复用你熟悉的更新逻辑即可:
- 安装依赖:
yum install -y p7zip p7zip-plugins
- 执行更新命令,更新完成后jar保留可执行属性,可直接运行:
7za u myjar.jar the/path/where/my/file/is/myfile
方案2:原生工具手动处理(无需安装额外依赖)
通过提取前导脚本+标准jar更新的方式实现,全程使用系统自带命令,可直接写入自动化脚本:
# 1. 查找标准zip结构的起始偏移量 offset=$(grep -ab -o $'PK\003\004' myjar.jar | head -n 1 | cut -d: -f1) # 2. 提取标准jar部分 dd if=myjar.jar of=standard_tmp.jar bs=1 skip=$offset 2>/dev/null # 3. 用标准jar命令更新文件 jar -uf standard_tmp.jar the/path/where/my/file/is/myfile # 4. 拼接前导脚本和更新后的jar,生成新的可执行文件 dd if=myjar.jar of=updated_myjar.jar bs=1 count=$offset 2>/dev/null cat standard_tmp.jar >> updated_myjar.jar chmod +x updated_myjar.jar # 5. 清理临时文件 rm -f standard_tmp.jar
方案3:关闭可执行属性(如果不需要直接./运行jar)
如果你的部署场景是通过java -jar命令启动服务,不需要直接执行jar,可以修改maven插件配置,关闭可执行属性:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>false</executable> <mainClass>com.my.app.Application</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
修改后打包生成的是标准jar包,直接使用jar -uf命令即可正常更新文件。
内容的提问来源于stack exchange,提问作者Baptiste
相关产品推荐
相关产品推荐

