Spring Boot打Jar包后JS无法读取resources目录文件如何解决
问题根因
IDEA运行正常、Jar包运行返回空,核心是两个问题:
- 原有
$resources()扫描逻辑存在局限性:IDEA启动时资源以真实文件形式存在于target/classes或target/test-classes目录下,基于文件系统遍历的正则匹配可以正常命中;但Spring Boot可执行Jar中的资源是压缩包内的嵌套条目,不存在独立的文件系统路径,原扫描逻辑无法遍历Jar内部的资源条目,直接返回空结果。 - 你贴出的代码存在变量名笔误:定义的资源数组名为
featuresResources,for循环内遍历的变量写为featureResources(少了末尾的s),该问题修复前即使资源扫描正常也会触发引用错误。
修复步骤
1. 替换资源扫描逻辑,兼容Jar包内资源读取
不要用基于文件系统遍历的扫描方式,直接调用Spring原生提供的PathMatchingResourcePatternResolver做类路径资源扫描,该组件原生支持文件系统、Jar包内嵌套资源的匹配,且通过流读取内容,不依赖资源的物理文件路径。
如果你的JS运行在JVM脚本引擎(Nashorn/GraalJS)环境,可以直接在JS代码中调用Java类,修改后的代码如下:
function processFeatures() { var features = []; // 初始化Spring资源解析器 var resourceResolver = new org.springframework.core.io.support.PathMatchingResourcePatternResolver(); // classpath*: 前缀会扫描所有类路径条目(包括Jar包内的资源),匹配所有.feature后缀文件 var featureResources = resourceResolver.getResources("classpath*:feature/*.feature"); for (var i = 0; i < featureResources.length; i++) { var resource = featureResources[i]; // 通过输入流读取资源内容,避免直接访问文件路径导致Jar内资源读取失败 var inputStream = resource.getInputStream(); var content = org.springframework.util.StreamUtils.copyToString( inputStream, java.nio.charset.StandardCharsets.UTF_8 ); inputStream.close(); // 原有业务解析逻辑 var feature = JSON.parse(content); features.push(feature); } return features; }
如果你是在自定义的$resources()工具方法中实现的扫描逻辑,直接修改该方法的底层实现,替换为上述Spring解析器的扫描逻辑即可,上层业务代码不需要调整。
2. 确认打包配置正确包含feature资源
Spring Boot构建时默认只会把src/main/resources下的资源打入生产Jar包:
- 如果你的
.feature文件存放在src/test/resources/feature路径下,默认不会被打入生产Jar,需要把文件移动到src/main/resources/feature路径下,或者调整构建插件配置,在打包时显式包含test路径下的feature目录。 - 如果是Maven项目,检查
pom.xml中maven-resources-plugin的配置,不要把*.feature文件加入排除规则;如果是Gradle项目,调整processResources任务的包含规则,确保feature文件被拷贝进Jar包。
3. 验证Jar包资源完整性
打包完成后可以解压Jar包,检查BOOT-INF/classes/feature/路径下是否存在你需要的a.feature、b.feature文件,如果Jar包本身没有包含对应资源,任何读取逻辑都会失效。
内容的提问来源于stack exchange,提问作者RAJESHPODDER007
相关产品推荐
相关产品推荐

