8

I'm Facing a FileNotFoundException while loading a JSON file which is in class path of Java jar using docker containers, it is a Spring-Boot application. This JSON file is available in resource folder . I'm Able to see the JSON file in docker under ./target/classes/ path.

Resource resource = resourceLoader.getResource("classpath:folderNm/file.json");
HashMap<String, String> headerMapping = (HashMap<String, String>) parser.parse(new FileReader(resource.getFile().getAbsolutePath()));

But I get this exception:

java.io.FileNotFoundException: class path resource [folderNm/file.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/folderNm/file.json

I tried

-> resource.getFile().getPath(); -> resource.getFile().getCanonicalPath(); -> "./target/classes/folderName/fileName" (hardcoded FilePath location) -> "/app.jar!/folderNm/file.json" (hardcoded FilePath location)

InputStream inputStream = getClass().getResourceAsStream("xyz.json");
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = br.readLine()) != null)
                responseStrBuilder.append(inputStr);

none of the way above are running. Kindly Suggest a way to resolve this issue.

Joe
  • 41,484
  • 20
  • 104
  • 125
Anvesh Reddy
  • 171
  • 1
  • 5
  • Have you tried with Resource resource = resourceLoader.getResource("classpath:/folderNm/file.json"); with leading forward slash? – Anton Belev Oct 06 '16 at 13:15
  • I've faced similar problem. And actually it turned out for me that it would be better to simply add the file while building docker image, and then access it simply with path. I'm not sure if you can do it the other way around. You need to remember that spring boot underneath uses tomcat/jetty/undertow embedded. – gmaslowski Oct 06 '16 at 13:26
  • @AntonBelev, I tried with leading / as well, but that did not worked. – Anvesh Reddy Oct 09 '16 at 07:13
  • @gmaslowski, Can you please show few lines as to how you could read the file from docker image? – Anvesh Reddy Oct 09 '16 at 07:19
  • Following code has worked for me. First I have added JSON file using maven in class path. Second in java i used below code String parsedJSONString = ""; ClassPathResource cpr = new ClassPathResource(filePath); byte[] bdata = null; try {bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream()); } catch (Exception e1) { e1.printStackTrace(); } parsedJSONString = new String(bdata, StandardCharsets.UTF_8); – Anvesh Reddy Oct 09 '16 at 07:29

2 Answers2

4

Assuming that in the maven structure (you are using maven, right?) your file is located at src/main/resources/folderName/file.json, the path you pass to getResourceAsStream should be /folderName/file.json

Actually everything is explained in javadocs:

Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:

  • If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
  • Otherwise, the absolute name is of the following form: modified_package_name/name

Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

Basically if you skip the '/' in front, it looks for the folderName inside the package of your class. Following code works fine for me:

    InputStream inputStream = StackTest.class.getResourceAsStream("/folderName/file.json");
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
    StringBuilder responseStrBuilder = new StringBuilder();
    String inputStr;
    while ((inputStr = br.readLine()) != null)
        responseStrBuilder.append(inputStr);
    System.out.println(responseStrBuilder.toString());

assuming I have my file.json in src/main/resources/folderName. I don't think it has anything to do with docker. Btw, I think you could make use of Apache Commons IOUtils.toString that helps turning InputStream into a String.

makasprzak
  • 5,082
  • 3
  • 30
  • 49
0

Create file:

src/main/resources/firebase/your_account_json.json

Load InputStream:

String path = "/firebase/your_account_json.json";
InputStream in = this.getClass().getResourceAsStream(path);
FirebaseOptions options = new FirebaseOptions.Builder().setCredentials(GoogleCredentials.fromStream(in))
      .setDatabaseUrl("https://your-project.firebaseio.com")
      .setStorageBucket("your-project.appspot.com")
      .build();
Pierry
  • 979
  • 7
  • 17