代码之家  ›  专栏  ›  技术社区  ›  wosimosi

Docker:无法从spring引导应用程序读取类路径资源

  •  0
  • wosimosi  · 技术社区  · 7 年前

    将类路径资源读取为,

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

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

    但是当运行这个应用程序时 docker运行-p 8080:8080应用程序映像 我可以点击应用程序终结点,从应用程序日志中可以看到它无法读取此文件(以下是日志中的内容),

    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 回复  |  直到 7 年前
        1
  •  2
  •   Alien    7 年前

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

    改变

    (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

        2
  •  4
  •   the hand of NOD    7 年前

    由于您使用的是springboot,因此可以尝试使用以下注释来加载类路径资源。为我工作,因为我也有同样的例外。注意目录“location”必须在 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 会是最好的选择。

        3
  •  0
  •   VC2019    7 年前

    同样的问题,这个文件在运行SpringBoot应用程序时工作,但在Docker中不工作。通过对资源使用ClassPathResource并使用InputStreamReader将资源读取为流,我的问题得到了解决。

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

    ....