Spring Boot: Loading files from resources

Spring Boot: Loading files from resources


Load File from "resources" folder

How to load files from "resources" folder in a maven project?
Everyone knows how to do that. Something like
File file = ResourceUtils.getFile("classpath:assets/data.json");
Or better, use Spring autowired ResourceLoader as
File file = resourceLoader.getResource("classpath:assets/data.json").getFile();

Then why this article?

Once you have your code ready, you will run your service as
mvn spring-boot:run

Service runs as expected.

But this is not how a service is run on a server. I would move the self-executable JAR to server. Preferably into a docker container. And then you see this: a java.io.FileNotFoundException!

java.io.FileNotFoundException: class path resource [assets/data.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/Users/hsingh/study/spring/demo-load-from-resources/target/demo-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/assets/data.json

at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)

at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:180)

at com.example.demo.LoadFileController.getFile(LoadFileController.java:18)

...

What just happened?

Hint: it does not reside in the file system

ResourceUtils is trying to access file on "file system". And a file inside JAR is not technically on the "file system". So ResourceUtils throws an exception.

Problem lies with "File" class. It cannot access a file inside a JAR. For "File" class, the JAR is itself a file.

It worked when we did "mvn spring-boot:run" because at that time "resources" folder was available on file system.

Solution

Load file as a stream. 

@Autowired private ResourceLoader resourceLoader;

 And then where you wish to load resource

InputStream inputStream = resourceLoader.getResource("classpath:assets/data.json").getInputStream();

This approach works because we do not have "File" class anywhere in call stack.

What if I don't want to read file. I want to do folder walk. Then use java.nio.file.Path.

        Path path = Paths.get(resourceLoader.getResource("classpath:" + basePath).getURI());

Comments