Docker:无法从 Spring Boot 应用程序读取类路径资源

wos*_*osi 4 java-8 docker spring-boot windows-10 dockerfile

读取类路径资源,

    try {
        final ClassPathResource classPathResource = new ClassPathResource(format("location%sGeoLite2-City.mmdb", File.separator));
        final File database = classPathResource.getFile();
        dbReader = new DatabaseReader.Builder(database).build();
    } catch (Exception e) {
        System.out.println("Exception: " + e);
    }
Run Code Online (Sandbox Code Playgroud)

我已经使用以下 Dockerfile 将它与 docker 打包在一起,

FROM java:8
ADD build/libs/*.jar App.jar
CMD java -jar App.jar
Run Code Online (Sandbox Code Playgroud)

但是在以docker run -p 8080:8080 app-image运行此应用程序时,我可以访问应用程序端点,并且从应用程序日志中我可以看到它无法读取此文件(以下来自日志),

Exception: java.io.FileNotFoundException: class path resource [location/GeoLite2-City.mmdb] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/App.jar!/BOOT-INF/classes!/location/GeoLite2-City.mmdb
Run Code Online (Sandbox Code Playgroud)

感谢您的任何评论,在您发表评论之前要了解的事情,

**- 在 windows 10、intellij 2018.2、jdk 8 上
运行 - 可以使用 intellij 和命令行成功运行应用程序 - 文件存在于 jar 中(我确实提取了 jar 并检查了)**

the*_*NOD 9

由于您使用的是 springboot,您可以尝试使用以下注释来加载类路径资源。为我工作,因为我有同样的例外。请注意,目录“位置”必须在src/main/resources文件夹下:

@Value("classpath:/location/GeoLite2-City.mmdb")
private Resource geoLiteCity;
Run Code Online (Sandbox Code Playgroud)

没有 springboot 你可以尝试:

try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/location/GeoLite2-City.mmdb")) {
... //convert to file and other stuff
}
Run Code Online (Sandbox Code Playgroud)

之前的答案也是正确的,因为“/”的使用根本不好,File.separator将是最佳选择。


Ali*_*ien 3

使用斜杠不是一个好方法。

始终使用文件分隔符,因为它们的工作与系统操作系统无关。

改变

(location\\GeoLite2-City.mmdb)
Run Code Online (Sandbox Code Playgroud)

("location"+ File.separator +"GeoLite2-City.mmdb")
Run Code Online (Sandbox Code Playgroud)

请参阅此了解更多信息。

https://www.journaldev.com/851/java-file-separator-separatorchar-pathseparator-pathseparatorchar

路径中 File.separator 和斜杠之间的区别