嵌套 JAR 扫描报 EOF
Spring Boot 嵌套 JAR 扫描报 ZLIB EOF,可能来自 NestedByteChannel 部分读取后返回零。确认读取路径,再选兼容的展开布局或实际包含修复的版本。
Spring Boot 应用能启动,自定义类路径扫描器读取 BOOT-INF/lib 中的依赖时,却报 Unexpected end of ZLIB input stream。如果扫描器把嵌套 JAR 转成 Path,再用 Files.newInputStream 和 ZipInputStream 读取,要检查 Boot 的 NestedByteChannel 返回值,不能只认定依赖包损坏。
字节已读,计数却是零
这条通道在缓冲区尚未填满、底层后续读取结束时,可能已经复制了一部分字节。受影响实现却返回 0,没有返回本轮累计的 total,上层输入流因此没有得到正确的读取计数,最终表现为压缩流提前结束。
已确认的场景涉及 Spring Boot 4.0.8;核对的 4.1.1 标签也仍保留这条返回分支。它不覆盖所有 ZLIB EOF:下载中断、真实归档截断或读取了错误文件,仍需先排除。
从完整堆栈和扫描代码确认读取路径,再对比构建产物校验值与实际嵌套条目。只在开发环境读普通 JAR 成功,不能证明部署后的嵌套文件系统路径也正常。
先绕开嵌套通道
如果当前部署允许改变归档布局,可使用 Boot tools 模式生成高效的展开布局。以下要求原归档包含 tools 模式、兼容该命令,并在构建阶段使用新的空目录:
java -Djarmode=tools -jar application.jar extract --destination extracted
结果包含应用 JAR 和外置依赖文件,启动时使用展开目录中的应用 JAR及其配套依赖,不是再运行原来的大归档。保留整个生成布局、原启动参数和工作目录约定。
扫描器也要能识别外置 JAR 的普通文件地址。若代码只会提取原嵌套 URL,不能只解包后照旧运行;检查资源发现逻辑是否还找得到所有需要的类与资源。不要通过忽略 EOF 或跳过出错依赖来让启动表面成功。
修复版本要看实际产物
代码修复已将“读过部分字节后返回零”改为返回累计字节数,并加入相应回归测试。该项列在 4.0.9 计划中,但截至 2026 年 10 月 14 日,这个版本尚未正式发布,不能把它写成当前可直接安装的修复。
正式修复可用后,按项目兼容要求采用确实包含改动的版本,并重新打包;仅改依赖声明却继续运行旧归档,不会更换其中的 loader。验收应覆盖原先失败的完整依赖扫描和应用功能,确认没有漏掉条目。这里不需要在已部署 JAR 内手工修改字节码。


