【问题标题】:FileSystemNotFoundException in a Dockerized Spring Boot ApplicationDockerized Spring Boot 应用程序中的 FileSystemNotFoundException
【发布时间】:2019-02-27 00:00:09
【问题描述】:

我正在尝试在 Docker 容器内运行的 Spring Boot 应用程序中加载文件,但出现以下异常:

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!/:?] 

我在容器外执行jar时没有出现错误。

这里是 Dockerfile:

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

这是加载文件的方法:

    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;
}

文件位于资源文件夹中:

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

传递给方法的参数是:

"database/file.sql"
  • 有人知道问题的原因及其可能的解决方案吗?

【问题讨论】:

    标签: java spring-boot docker


    【解决方案1】:

    我认为通过在容器外执行 jar 意味着在 IDE 中运行项目。那么database/file.sql实际上是作为文件可用的。

    在 jar 中,Paths.get() 无法实际处理该文件。

    当你试图访问你应该使用的资源时

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

    然后您可以使用java.util.Scanner 收集行:

    String data = new Scanner(in)
     .useDelimiter('\n')
     .tokens()
     .collect(Collectors.joining(StringUtils.SPACE));
    

    【讨论】:

    • 内部Files.lines 使用BufferedReader.lines。哪个可以在InputStream 和已经使用的代码之间链接。但是应该注意,关闭流并不会关闭它正在读取的阅读器。
    • 谢谢奥兹曼!你是对的,当我改变读取文件的方式时,问题就解决了。我还必须以这种方式更改论点:"/database/file.sql"。但由于我必须使用 Java 8,我无法使用 .tokens().collect(...) 方法。
    【解决方案2】:

    这个异常看起来是在处理 zip/archive 文件,请确认一下是在加载 sql 还是其他文件的时候?

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 2019-11-06
      • 2019-01-02
      • 2015-12-03
      • 2021-01-29
      • 2019-12-04
      • 2021-12-03
      • 2019-12-24
      • 1970-01-01
      相关资源
      最近更新 更多