Чтение ресурса classpath как,

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

Я упаковал это с помощью Docker, используя следующий Dockerfile,

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 и проверил) **

1
wosimosi 20 Авг 2018 в 14:26

3 ответа

Лучший ответ

Это плохой подход к использованию слешей.

Всегда используйте файловые разделители, так как они работают независимо от операционной системы.

+ Изменить

(location\\GeoLite2-City.mmdb)

К

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

Обратитесь к этому для более.

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

Разница между File.separator и косой чертой в путях

2
Alien 20 Авг 2018 в 11:43

При той же проблеме файл работал при запуске загрузочного приложения Spring, но не работал в Docker. Моя проблема была решена с помощью ClassPathResource для ресурса и чтения ресурса в виде потока с использованием InputStreamReader.

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

....

0
VC2019 15 Фев 2019 в 17:03

Поскольку вы используете springboot, вы можете попробовать использовать следующую аннотацию для загрузки вашего ресурса classpath. Работал на меня, потому что у меня было то же исключение. Помните, что каталог «location» должен находиться в папке src/main/resources:

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

Без весенней загрузки вы можете попробовать:

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

Кроме того, ответы ранее были правильными, так как использование «/» не очень хорошо, и File.separator будет лучшим выбором.

4
the hand of NOD 21 Авг 2018 в 07:21
51929777