Java 1.8升级至1.11后出现IllegalStateException: zip file closed错误求助
问题分析
从堆栈跟踪来看,错误发生在TessAPI类初始化阶段,根源是类加载器尝试访问Jar资源时,对应的Zip文件已被关闭。结合Java 8到11的版本变化、仅命令行运行失败的现象,核心问题大概率和Java 11的类加载/资源处理机制变化、打包方式兼容性或Tess4j的版本适配性有关。
解决策略
1. 确认Tess4j版本的Java 11兼容性
虽然你已更新版本,但需确保使用的Tess4j版本明确支持Java 11。建议直接升级到Tess4j 4.5.4及以上版本,该版本针对Java 9+的模块化环境做了适配,修复了部分资源加载的兼容性问题。同时要保证Tesseract DLL版本与Tess4j匹配,且为对应JVM位数(64位JVM需用64位DLL)。
2. 排查打包方式问题
Eclipse运行时直接加载项目目录中的类和依赖Jar,而命令行运行的打包Jar(如Maven Shade生成的fat jar)可能因配置不当触发错误:
- 若使用Maven Shade插件打包,添加以下配置避免资源冲突和Zip文件提前关闭:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>你的主类全路径</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> - 避免打包时覆盖Tess4j依赖Jar中的本地库资源,优先使用原依赖Jar的完整结构。
3. 调整资源加载逻辑(临时 workaround)
若升级Tess4j后问题仍存在,可手动修改LoadLibs的资源提取逻辑,绕开Java 11的ZipFile关闭机制:
// 替换原LoadLibs中获取TessAPI实例的资源加载代码 URL dllResource = LoadLibs.class.getResource("/libtesseract305.dll"); Path tempDll = Files.createTempFile("tess", ".dll"); try (InputStream is = dllResource.openStream()) { Files.copy(is, tempDll, StandardCopyOption.REPLACE_EXISTING); } System.load(tempDll.toAbsolutePath().toString()); // 使用后记得清理临时文件 tempDll.toFile().deleteOnExit();
4. 适配Java 11类加载器行为
Java 9+模块化系统改变了URLClassLoader的资源处理逻辑:Java 8中关闭getResourceAsStream返回的流不会关闭底层ZipFile,但Java 11会。针对此特性:
- 确保在
TessAPI初始化前,不要提前关闭任何从Jar中读取的资源流; - 启动命令中添加参数,开放类加载器所需的权限:
java --add-opens java.base/java.net=ALL-UNNAMED -jar 你的应用.jar
5. 验证命令行类路径
命令行运行时的类路径可能与Eclipse不一致,导致依赖Jar未正确加载:
- 使用完整类路径参数运行,确保所有依赖Jar都被包含:
java -cp "lib/*;你的应用.jar" 你的主类全路径
内容的提问来源于stack exchange,提问作者arcy
相关产品推荐
相关产品推荐

