Java 10升级后getResourceAsStream返回null问题排查求助
分析Java 10升级后静态方法中getResourceAsStream返回null的问题
这个问题我之前帮不少开发者排查过,核心原因和Java 9开始引入的**模块系统(JPMS)**以及类加载器行为变化有关,具体拆解如下:
一、最可能的根源:误用了JDK核心类的类加载器
你在静态方法里调用的是appProperties.getClass().getResourceAsStream("/application.properties"),而appProperties是Properties类的实例——Properties是JDK核心类,它的类加载器是启动类加载器(Bootstrap ClassLoader)。
在Java 8中,启动类加载器的访问范围相对宽松,可能还能间接访问到应用类路径下的资源;但Java 9+的模块系统严格划分了类加载器的权限,启动类加载器只能加载JDK核心模块的资源,完全无法访问你的应用类路径(比如src/main/resources)下的文件,所以必然返回null。
二、其他可能的影响因素
- 模块化应用的资源权限限制
如果你的项目已经添加了module-info.java转为模块化应用,默认情况下,模块不会对外暴露自身的资源。即使资源存在,若没有在module-info.java中声明开放,也会导致加载失败。 - 资源打包路径异常
升级Java版本时如果同步升级了构建工具(Maven/Gradle),可能会因为插件配置变化,导致application.properties没有被正确打包到类路径根目录(比如target/classes或Jar包根目录)。
三、快速解决方案
方案1:改用当前业务类的类加载器(最推荐)
在静态方法中,用你自己的业务类的类加载器来加载资源,而不是Properties实例的类加载器:
// 方式1:用当前类的getResourceAsStream(带斜杠表示类路径根) YourStaticMethodClass.class.getResourceAsStream("/application.properties"); // 方式2:用当前类的类加载器(不需要斜杠,直接从类路径根查找) YourStaticMethodClass.class.getClassLoader().getResourceAsStream("application.properties");
这两种方式都是用**应用类加载器(Application ClassLoader)**来加载资源,它能正常访问你的应用类路径下的文件。
方案2:如果是模块化应用,配置module-info.java
如果你的项目是模块化的,需要在module-info.java中声明允许访问资源:
module your.module.name { // 允许JDK核心模块访问你的根路径资源 opens . to java.base; // 或者直接声明包含该资源文件 resources "/application.properties"; }
方案3:验证资源打包结果
检查构建后的产物(比如target/classes目录或Jar包),确认application.properties是否存在于根目录下。如果缺失,调整Maven/Gradle的resources插件配置,确保资源被正确复制。
内容的提问来源于stack exchange,提问作者Pablo Fernandez
相关产品推荐
相关产品推荐

