1

I am having trouble accessing a resource file at runtime, which is stored in the resources folder of my JAVA project.

The project is Spring Boot based and I have stored some ddl and json configuration files under src/main/resources. The project gets deployed correctly (through Maven). However, when my code tries to access one of those resource files I get the following exception:

java.nio.file.NoSuchFileException: file:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/app_data_schema.ddl

I can see from the logs that just before this exception another file gets loaded correclty by Spring from the same location (file:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/schema.sql).

I have also double checked using the heroku CLI ("heroku run bash") that indeed the files have been deployed to the location I am expecting: /app/target/classes/setup_data - test_app_data1.json
- test_app_data2.json
- app_data_schema.ddl

This leads me to believe that the problem is in the way I am loading the files, which works locally on my machine but not when deployed to Heroku. This is the code I am using to figure out the full path of the file:

public static String getFullPathForResource(Class<?> resourceClass, String resourceName) {
    URL resourceUrl = resourceClass.getResource(resourceName);
    String fullPath = "";
    if (resourceUrl != null) {
        fullPath = resourceUrl.getPath();
    }

    return fullPath;
}

I then load the file as follows:

String ddlResourceFullPath = getFullPathForResource(getClass(), ddlResource);
Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));

The result of the getFullPathForResource() method is indeed: "file:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/schema.sql"

Which from my understanding should match the correct path of my resource!

Could you guide me on to how to correclty load the resource file?

Thanks for your help!

edoDev
  • 551
  • 1
  • 4
  • 20

1 Answers1

1

I was pointed to the issue by Heroku's support.

The issue lied in the way I was loading the file, not how I was finding the path to the resource. Specifically, this line:

Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));

Files.lines expects the file to be on the file system and is not going to be able to open a file inside the Jar file.

Using java.lang.ClassLoader.getResourceAsStream() resolves the issue. (eg: MyClass.class.getResourceAsStream() )

Dharman
  • 30,962
  • 25
  • 85
  • 135
edoDev
  • 551
  • 1
  • 4
  • 20