Backend Development 5 min read

Resolving Spring Boot Resource Loading Errors When Running from a JAR

This article explains why a Spring Boot application fails to locate a template file when packaged as a JAR, details the step‑by‑step debugging process, and provides code solutions using ClassPathResource or PathMatchingResourcePatternResolver to correctly read resources inside the JAR.

Java Captain
Java Captain
Java Captain
Resolving Spring Boot Resource Loading Errors When Running from a JAR

When reading files from the resources directory, the code works locally but throws an error in the test environment: class path resource [xxxx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:xxxx.jar!/BOOT-INF/classes!xxxx .

1. Project Code

GetResourceTest :

public class GetResourceTest {
    public InputStream getResource1() throws IOException {
        File file = new DefaultResourceLoader().getResource("/template/qiankuan.ftl").getFile();
        return Files.newInputStream(file.toPath());
    }

    public InputStream getResource2() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("/template/qiankuan.ftl");
        Resource resource = resources[0];
        return resource.getInputStream();
    }
}

TestController :

@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping(value = "/getResource")
    @ResponseBody
    public void getResource() throws IOException {
        GetResourceTest getResourceTest = new GetResourceTest();
        getResourceTest.getResource1();
    }
}

2. Investigation Process

1) Build the project into a JAR with Maven

The mvn install command creates the JAR in the target directory.

2) Run the JAR with remote debugging

java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9992 api-test-1.0.0-SNAPSHOT.jar

The application starts successfully.

3) Add remote debugging configuration

In the IDE, add a Remote JVM Debug configuration and set the port to the one used above (e.g., 9992).

4) Call the test endpoint

Request: http://127.0.0.1:9991/test/getResource

5) Observe the error

The response shows the same FileNotFoundException as in the test environment.

6) Debug with breakpoints

Setting a breakpoint at the controller entry reveals that the resource path is resolved to a JAR URL like jar:file:/.../api-test-1.0.0-SNAPSHOT.jar!/BOOT-INF/classes!/template/qiankuan.ftl , and resourceUrl.getProtocol() returns jar instead of file , causing the exception.

3. Solution

The ResourceUtils.getFile() method only works for non‑compressed files and cannot read resources inside a JAR. Use a method that reads the resource as a stream, such as ClassPathResource or PathMatchingResourcePatternResolver :

ClassPathResource classPathResource = new ClassPathResource("/template/qiankuan.ftl");
InputStream inputStream = classPathResource.getInputStream();

or

ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("/template/qiankuan.ftl");
Resource resource = resources[0];
InputStream inputStream = resource.getInputStream();

These approaches correctly load the template file whether the application runs from the IDE or from a packaged JAR.

backenddebuggingJavaSpring Bootresource-loadingJar
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.