Grails 3.3.8读取src/main/resources下文件失败求解决方案
解决Grails 3.3.8中读取resources目录下JS文件输入流的问题
我来帮你梳理下这个问题的核心原因和解决思路,你遇到的问题本质是Grails 3(基于Spring Boot)中资源访问的场景差异——开发环境下资源是文件系统里的真实文件,但打包成jar后,资源会被嵌入到jar内部,这时候直接用File类访问就会失效,这也是你能打印出路径但拿不到输入流的关键原因。
下面是具体的解决步骤和排查方向:
1. 使用Spring提供的ClassPathResource获取输入流(最可靠的方案)
Grails 3基于Spring Boot,直接用Spring封装的ClassPathResource可以无缝适配开发和生产环境(不管资源在文件系统还是jar包内),代码如下:
import org.springframework.core.io.ClassPathResource; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.IOException; import java.io.InputStream; // 在你的业务逻辑中 try (InputStream jsInputStream = new ClassPathResource("hl.js").getInputStream()) { ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval(jsInputStream); // 这里可以添加JS执行后的后续逻辑 } catch (IOException | ScriptException e) { // 记得处理异常,比如打印日志或抛出业务异常 e.printStackTrace(); }
这个方法会自动使用正确的类加载器加载src/main/resources下的hl.js,不需要关心资源是在文件系统还是jar包内。
2. 检查资源是否被正确打包到classpath
有时候可能因为配置问题,hl.js没有被正确打包到应用的classpath中:
- 开发环境下,去项目的
build/resources/main目录下查看是否有hl.js; - 如果是打包后的jar,解压jar包,检查根目录下是否存在
hl.js; - 如果没有找到,检查
grails-app/conf/application.yml的资源配置,确保没有排除该文件:grails: resources: pattern: '**/*' # 这个配置会包含resources下所有文件,默认一般是开启的
3. 分析之前方法失败的原因
你之前尝试的几种类加载器方法失败,大概率是类加载器上下文的问题:
this.class.classLoader.getResourceAsStream("hl.js"):某些Grails bean的类加载器可能和应用的类加载器不一致,导致找不到资源;- 用
getResource()拿到路径后转File:这个路径是开发环境下的文件系统路径,但打包成jar后,jar内的资源不是真实的文件,所以new File()会找不到文件,输入流自然为null。
4. 额外注意:资源流的关闭
一定要用try-with-resources语法(就像上面示例那样),它会自动关闭输入流,避免资源泄漏问题。
内容的提问来源于stack exchange,提问作者John Little
相关产品推荐
相关产品推荐

