为什么getResourceAsStream带双斜杠路径在单测可行在依赖调用时失效
问题根因解释
两种场景下加载资源使用的类加载器对路径的处理规则不同,具体差异如下:
- 单元测试场景的路径处理逻辑
Gradle 6运行JUnit测试时,默认不会把项目资源打包成jar后再测试,而是直接读取build/resources目录下的本地文件系统资源。本地文件系统的路径解析规则会自动将连续的斜杠//规范化为单个斜杠/,和操作系统路径解析逻辑一致,因此即使路径多写了一个斜杠,也能正常定位到foo/bar.txt文件。 - CLI应用调用场景的路径处理逻辑
CLI应用运行时,依赖的a.jar已经是打包完成的压缩包文件,此时类加载器会使用Jar包专属的资源寻址逻辑:直接匹配资源路径字符串,不会做斜杠规范化处理。此时你传入foo//bar.txt,类加载器会在Jar包的资源索引里精确查找路径为foo//bar.txt的条目,但Jar包里实际只有foo/bar.txt,因此匹配失败返回null。
补充说明:
javaClass.getResourceAsStream的路径处理规则完全由当前类对应的类加载器实现决定,不存在统一的斜杠规范化要求,因此生产环境调用该API时必须严格使用单斜杠分隔的标准资源路径。
内容的提问来源于stack exchange,提问作者Matthew Pope
相关产品推荐
相关产品推荐

