【问题标题】:Docker: Can't read class path resource from spring boot applicationDocker:无法从 Spring Boot 应用程序读取类路径资源
【发布时间】:2018-08-20 11:26:59
【问题描述】:

将类路径资源读取为,

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

我已使用以下 Dockerfile 将其与 docker 打包,

FROM java:8
ADD build/libs/*.jar App.jar
CMD java -jar App.jar

但是在以 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

感谢任何评论,评论前须知,

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

【问题讨论】:

  • 如果您能够在命令行上运行应用程序,我假设您的文件确实在 jar 中,所以它可能是“\\”标志?我也在 Windows 上用“/”阅读了我的类路径资源。
  • @thehandofNOD 确实,文件存在于 Jar 中,我修复了 \\,仍然无法工作。

标签: docker spring-boot java-8 windows-10 dockerfile


【解决方案1】:

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

@Value("classpath:/location/GeoLite2-City.mmdb")
private Resource geoLiteCity;

没有springboot你可以试试:

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

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

【讨论】:

  • 是的,通过将资源读取为流而不是文件来修复它。
【解决方案2】:

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

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

改变

(location\\GeoLite2-City.mmdb)

("location"+ File.separator +"GeoLite2-City.mmdb")

更多信息请参考这里。

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

Difference between File.separator and slash in paths

【讨论】:

  • 已按 File.separator 更新,但仍无法正常工作,请相应更新,谢谢。
【解决方案3】:

有同样的问题,该文件在运行 Spring Boot 应用程序时有效,但在 Docker 中无效。通过对资源使用 ClassPathResource 并使用 InputStreamReader 将资源作为流读取,我的问题得到了解决。

Resource resource = new ClassPathResource("test-xyz.json");
InputStream inputStream = null;
        try {
            inputStream = resource.getInputStream();
            Reader reader = new InputStreamReader(inputStream, "UTF-8");

....

【讨论】:

    猜你喜欢
    • 2018-03-17
    • 2015-02-02
    • 2017-09-11
    • 2020-07-21
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多