如何将嵌套依赖jar的非fat jar转为符合类层级要求的fat jar?
嵌套JAR扁平化处理实现指南
应用场景与约束
- 目标运行环境强制要求所有类文件必须处于Jar包的同一基础层级,不支持Jar内嵌套Jar的结构,遇到嵌套Jar会直接运行失败
- 开发的应用面向终端用户分发,无法提前管控用户本地是否持有现成的fat Jar,因此必须把所有依赖的类文件直接平铺到最终输出Jar的根路径,不能保留任何嵌套Jar结构
现有实现的性能缺陷
最初的可行思路是借助JarFile类读取Jar条目,每次遇到嵌套Jar文件时,就把该Jar写出为独立临时文件,再重复执行解析处理流程;但这种方式仅为了获取嵌套Jar的内部条目列表,就要反复执行文件复制操作,会造成不必要的磁盘IO、内存浪费,大幅拖慢构建速度。
结构示例
原始嵌套Jar结构
test.jar ├─ com.package │ └─ main.class └─ dependency1.jar └─ com.dependency1 └─ test.class
目标扁平化Jar结构
test.jar ├─ com.package │ └─ main.class └─ com.dependency1 └─ test.class
优化处理方案
全程避免嵌套Jar落地磁盘的冗余操作,直接在内存流中完成解析:
- 遍历外层Jar的所有条目时,遇到后缀为
.jar的条目,不写出为临时文件,直接将条目对应的输入流传给内存Jar解析器读取内部内容 - 逐一把嵌套Jar内的类文件、资源文件,按照原有的包路径直接写入最终输出的Jar包
- 自动跳过嵌套Jar内的签名校验文件、空目录等冗余条目,只将实际可运行的类和业务资源平铺到输出Jar的对应路径下
- 处理过程中维护已写入条目的路径集合,避免同一路径的类文件被重复写入造成冲突
内容的提问来源于stack exchange,提问作者JFJB Games
相关产品推荐
相关产品推荐

