You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:55:46