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

JDK18环境下jar包内资源getResourceAsStream加载返回null问题

问题现象

从jar包中加载用于构建ImageIcon的png图片资源的功能已稳定运行18年,在Hotspot Java 1.8.0_333版本下可正常工作,但在Hotspot Java 18.0.1.1版本下运行时会出现资源加载失败问题。测试全程使用同一个jar包,已确认包内确实包含目标资源文件。

问题复现代码如下:

String fileName = "/images/logo.png";
ImageIcon image = new ImageIcon();

byte[] imageBytes = null;
InputStream in = image.getClass().getResourceAsStream(fileName);
if (in == null) {
  System.out.println("could not find " + fileName);
}

使用Java 18.0.1.1版本运行上述代码时,输入流in实际返回值为null。

版本差异说明

getResourceAsStream的资源查找逻辑确实在Java 9版本开始发生了本质变化,核心原因是Java 9引入了模块化系统(JPMS),调整了类加载器的资源扫描规则:

  • Java 8及更早版本:ImageIcon是rt.jar中的核心类,由启动类加载器加载,当时启动类加载器的资源查找范围覆盖整个应用classpath,传入以/开头的绝对路径时,可以正常找到应用jar包内的资源文件。
  • Java 9及更高版本(包括18.0.1.1):Java核心类被拆分到独立的运行时模块中,启动类加载器加载的核心类调用getResourceAsStream时,默认只会扫描所属运行时模块内部的资源,不会主动查找应用classpath/modulepath下的自定义资源,因此直接返回null。
修复方案

两种改法都可以解决问题:

  • 不要用JDK核心类的Class对象调用getResourceAsStream,换成你自己项目中自定义类的Class对象调用,比如这段代码所在的当前类的Class对象,自定义类由应用类加载器加载,会正常扫描应用jar包内的资源。
  • 直接获取上下文类加载器加载资源,注意类加载器加载资源时路径不要带开头的/,代码示例:
InputStream in = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream("images/logo.png");

内容的提问来源于stack exchange,提问作者Jack D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:42:14