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

Java命名模块项目中getResource两种调用方式差异及返回null原因分析

核心原因:Java 9+ 命名模块的资源访问封装规则限制

注意:本项目为Java命名模块(named-module)项目

两种调用的底层逻辑差异如下:

第一种调用成功的原因

ClassNameOne.class.getResource("/resPath/tmp.txt") 是用mod-one模块自身的类ClassNameOne,访问同属于mod-one模块下的资源,不受模块封装规则限制,只要路径正确就能正常返回对应URL。

第二种调用返回null的原因

虽然你传入了mod-one的ClassNameOne.class作为参数,但getCustomRes方法是定义在mod-two模块中,属于跨模块访问mod-one的资源。
Java命名模块的资源访问规则明确要求:跨模块访问其他模块的资源时,被访问的模块必须主动开放对应资源目录的访问权限给调用方模块,否则JVM会直接拦截访问请求返回null,和资源路径是否正确无关。


两种常用修复方案

  • 方案一:在mod-one的module-info.java中开放对应资源目录给mod-two,添加如下配置即可:
    // mod.two替换为你mod-two模块的实际声明名称
    opens resPath to mod.two;
    
  • 方案二:调整资源获取逻辑,改用类加载器绕开模块资源访问限制,修改getCustomRes的逻辑:
    // 类加载器的getResource方法无需加开头的斜杠,直接传相对类路径的路径即可
    url = sourceClass.getClassLoader().getResource(sourcePath);
    
    类加载器是在整个模块路径下全局搜索资源,不受模块封装规则限制,只要资源在类路径/模块路径下存在就能正常返回。

补充命名模块资源访问通用规则

  • 模块内类访问自身模块的资源:无任何限制
  • 跨模块访问其他模块的资源:被访问模块必须通过opens指令开放对应目录给调用方模块
  • 用ClassLoader.getResource/getResourceAsStream获取资源:不受模块封装规则限制,全局搜索所有可加载的资源

内容的提问来源于stack exchange,提问作者Liveon Phoenix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:36:06