0

Whenever I run this code locally, the relative path for the file is working just fine but the Kubernetes pod deployment in pre-prod throws NoSuchFileException.

MOCK_DATA_BASE_PATH = "/data/mocks"
private static String getMockDataString(String fileName) {
        try {
            String filePath = MOCK_DATA_BASE_PATH + fileName;
            return Files.lines(Paths.get(filePath))
                    .collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            logger.error("Unable to read file {} with reason {}", fileName, e.getMessage());
        }
        return null;
}

When I checked what my local returns for Path projectRoot = Paths.get("").toAbsolutePath(); it returned a local machine specific absolute path like so:/Users/username/path/to/project/mavenModule while the Kubernetes deployment is plainly showing /. Given such difference in both, I'm wondering how I can read the file in both platforms without exception.

The project directory is as such: Project has 3 mvn module1/module2/module2 directories. The files are in path/to/Project/data/mocks/

Real code examples of alternatives would be highly appreciated

5
  • 2
    You cannot use a Paths and Files to load from t he classpath (that is in the end what you are doing). Use an InputStream for reading like getClass().getResourceAsStream(<your-location>). Commented Nov 13, 2024 at 8:18
  • Is this data bundled as part of your application, or is it something else? In the Kubernetes environment, how does it get into the Pod? I'd probably use @M.Deinum's suggestion, moving the data files into moduleN/src/main/resources, and then it the data will be bundled into the jar file and independent of the filesystem path. Commented Nov 13, 2024 at 10:35
  • 3
    There is no point in splitting a file into lines, just to join the lines again afterwards. Simply use Files.readString(…). Unless you really want to replace the platform independent line separators with System.lineSeparator() which is highly doubtful. Commented Nov 13, 2024 at 12:48
  • 1
    @M.Deinum actually, you can use Path and Files to load from classpath. You just have to use the right filesystem rather than the default filesystem. But, of course, for a single resource, just using getResourceAsStream is simpler. Commented Nov 13, 2024 at 12:51
  • Looks like you're concatenating without a file separator character. You should do Path p = Path.of(MOCK_DATA_BASE_PATH, fileName);return Files.readString(p); Commented Nov 13, 2024 at 12:58

2 Answers 2

0

Based on the comments I managed to make this approach work:

private static String getMockDataString(String fileName) throws MyServiceException {
        String filePath = MOCK_DATA_BASE_PATH + fileName;
    try (InputStream inputStream = MockResponseUtils.class
            .getClassLoader().getResourceAsStream(filePath)) {
        if (inputStream != null) {
            return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
        }
    } catch (IOException e) {
        throw new MyServiceException("Unable to load mock data for file " + MOCK_FILENAME);
    }
    return null;
}
Sign up to request clarification or add additional context in comments.

1 Comment

You don't need 3rd party classes. Just return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
-2

You can put MOCK_DATA_BASE_PATH as a variable in your environment

or put to resource directory and filename will be searched in resource

or link like classpath:somedir/file.txt

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.