docker环境加载包内资源文件FileNotFoundException

在docker容器中运行springboot时,报错“文件找不到”, 代码如下:

File file = new File(jasperFileCommonBegin);

资源文件路径:

--src
----main
------java
------resource
--------jasper
----------COMMON_BEGIN.jasper

关键日志如下:

2023-02-28 09:20:50.903 ERROR 1 --- [ncBatchThreads3] o.s.batch.core.step.AbstractStep : Encountered an error executing step PN2000P-Job1Step2 in job PN2000P-Job1

net.sf.jasperreports.engine.JRException: java.io.FileNotFoundException: jasper/COMMON_BEGIN.jasper

at net.sf.jasperreports.engine.util.JRLoader.loadObject(JRLoader.java:128) ~[jasperreports-6.19.1.jar:6.19.1-867c00bf88cd4d784d404379d6c05e1b419e8a4c]

at net.sf.jasperreports.engine.util.JRLoader.loadObject(JRLoader.java:117) ~[jasperreports-6.19.1.jar:6.19.1-867c00bf88cd4d784d404379d6c05e1b419e8a4c]

at stb.op.batch.report.pn2000p.step2.Step2GeneratePdfTasklet.execute(Step2GeneratePdfTasklet.java:60) ~[classes/:na]

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.6.jar:5.3.6]

at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.2.jar:4.3.2]

at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.2.jar:4.3.2]

at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.2.jar:4.3.2]

at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:94) ~[spring-batch-core-4.3.2.jar:4.3.2]

at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:91) ~[spring-batch-core-4.3.2.jar:4.3.2]

at java.base/java.util.concurrent.FutureTask.run(Unknown Source) ~[na:na]

at org.springframework.core.task.SimpleAsyncTaskExecutor$ConcurrencyThrottlingRunnable.run(SimpleAsyncTaskExecutor.java:280) ~[spring-core-5.3.6.jar:5.3.6]

at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

Caused by: java.io.FileNotFoundException: jasper/COMMON_BEGIN.jasper

... 23 common frames omitted

分析:看上去正在加载src/main/resources/jasper/COMMON_BEGIN.jasper,该文件仅在应用程序源代码可用并且工作目录是源代码树的根目录时才存在,如果你在没有可用源的情况下运行 jar 文件,你会在 Docker 等容器中看到同样的报错异常。

方案:应该从类路径加载文,而不是从文件系统加载文件,src/main/resources 中的任何文件都可以从类路径的根目录中获得。您可以使用从ConfigurationReader.class.getClassLoader().getResourceAsStream("jasper/COMMON_BEGIN.jasper") 返回的InputStream 加载。或者当使用 Spring Boot 时,改用 Spring Framework 的 ClasspathResource

具体代码如下:
 

// 因为Resouce是一个接口 所以我们可以使用它的实现类ClassPathResource来new一个对象。而构造方法的参数便是resources目录下的文件路径

//注意这里是使用的相对路径(相对于resouces目录而言)
Resource resource = new ClassPathResource("jasper/COMMON_BEGIN.jasper");

//我们获取到resource对象后,变可以调用resouce.getFile()方法来获取文件。
File file = resouce.getFile();

解决~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值