7

I'm trying to load a file in a spring boot application that is running inside a Docker container but I'm getting the following exception:

java.nio.file.FileSystemNotFoundException 
 at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171) ~[zipfs.jar:1.8.0_191] 
   at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157) ~[zipfs.jar:1.8.0_191] 
 at java.nio.file.Paths.get(Paths.java:143) ~[?:1.8.0_191] 
 at app.metrics.collector.util.FileUtils.getContentAsSingleLine(FileUtils.java:17) ~[classes!/:?] 
     at app.metrics.collector.jobs.DbQueryJob.generatePreparedStatement(DbQueryJob.java:54) ~[classes!/:?] 
at app.metrics.collector.jobs.DbQueryJob.execute(DbQueryJob.java:36) ~[classes!/:?] 
  at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [quartz-2.3.0.jar!/:?] 

The error does not appears when I execute the jar outside the container.

Here is the Dockerfile:

FROM openjdk:8-jdk-alpine
ADD build/app.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]

And here is the method that loads the file:

    public static String getContentAsSingleLine(String fileName) throws URISyntaxException, IOException {
    String data;
    Path path = Paths.get(FileUtils.class.getClassLoader().getResource(fileName).toURI());
    Stream<String> lines = Files.lines(path);
    data = lines.collect(Collectors.joining(StringUtils.SPACE));
    lines.close();
    return data;
}

The file is located in the resource folder:

/src/main/resources/database/file.sql

and the argument passed to the method is:

"database/file.sql"
  • Does anyone have an idea of the cause of the issue and its possible solution ?

2 Answers 2

8

I think by execute the jar outside the container you mean running the project in your IDE. Then database/file.sql is actually available as a file.

In the jar, the file is not available for Paths.get() to actually handle.

When trying to access the resource you should use

InputStream in = getClass().getResourceAsStream(fileName);

you can then use java.util.Scanner to collect the lines:

String data = new Scanner(in)
 .useDelimiter('\n')
 .tokens()
 .collect(Collectors.joining(StringUtils.SPACE));
Sign up to request clarification or add additional context in comments.

2 Comments

Internally Files.lines uses BufferedReader.lines. Which can link between the InputStream and the code already in use. It should however be noted that closing the stream does not close the reader it is reading from.
Thank you Ozman ! You were right the issue was solved when I changed the way to read the file. I also had to change the argument this way: "/database/file.sql". But as I have to use Java 8 I couldn't use the .tokens().collect(...) methods.
-1

The exception looks to be dealing with zip / archive file, please ensure once that whether it is while loading sql or any other file?

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.