Java 19中ClassLoader.getResource()返回null问题求助
问题解决:Java 19中ClassLoader.getResource返回null的修复方案
问题重现
代码示例:
@FXML private ImageView img; public void initialize(URL url, ResourceBundle rb){ try{ img.setImage(new Image(getClass().getClassLoader().getResource("icons/a.png").toURI().toString())); }catch(Exception ex){ System.out.println(ex); }
在Java 19环境运行时抛出错误:Cannot invoke java.net.URL.toURI() because the return value of java.lang.ClassLoader.getResource(String) is null,但Java 13可正常运行。
原因分析
Java 9+引入的模块系统(JPMS)改变了资源查找规则。如果项目以模块化方式编译运行,ClassLoader.getResource()无法直接访问模块内的非公开资源;而Java 13可能未启用严格的模块检查,或项目当时以非模块化方式运行,因此未触发该问题。
解决方法
方法1:改用当前类的getResource方法
替换getClass().getClassLoader().getResource()为getClass().getResource(),后者会适配模块系统的资源访问规则:
@FXML private ImageView img; public void initialize(URL url, ResourceBundle rb){ try{ // 路径开头的斜杠表示从模块根目录开始查找,和原逻辑一致 img.setImage(new Image(getClass().getResource("/icons/a.png").toURI().toString())); }catch(Exception ex){ System.out.println(ex); }
方法2:在模块声明中开放资源访问
若坚持使用ClassLoader方式,需在module-info.java中添加资源访问声明:
module your.module.name { opens icons to javafx.graphics; // 替换为你的实际模块名 }
说明:
opens允许反射访问指定目录的资源,若需公开资源包可改用exports。
方法3:以非模块化方式运行项目
如果不需要模块系统,可在编译运行时添加参数--add-modules javafx.controls,javafx.fxml,同时移除项目的模块声明,改用传统类路径方式运行,规避JPMS的资源限制。
内容的提问来源于stack exchange,提问作者JavaUser007
相关产品推荐
相关产品推荐

