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

时间:2018-08-20 11:26:59

标签: docker spring-boot java-8 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);
    }

我已使用以下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并检查了) **

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 :(得分:0)

存在相同的问题,该文件在运行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");

....