Не удается прочитать файл через контейнер docker

#java #spring-boot #docker #docker-compose

#java #весенняя загрузка #docker #docker-compose

Вопрос:

У меня есть приложение с весенней загрузкой, и у меня есть несколько файлов, размещенных внутри /src / main / java / resources, которые я пытаюсь прочитать в своем коде. Когда тот же код пытается прочитать из контейнера docker, он сообщает, что файл не существует. Тот же код отлично работает через localhost

Файлы находятся в папке /src / main / java / resources / data, и это мой код, который пытается прочитать файл

  private String getJson(String folderName, String id, StringBuilder sb) throws Exception {
        String responseJson = null;
        String filePath = "data"   File.separator   folderName   File.separator   id   ".json";
        LOG.info("printing filePath : "   filePath);
        LOG.info("printing id : "   id);
        File f = new File(filePath);
       // if(f.exists()){
            try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
                LOG.info("printing inputStream : "   inputStream);
                if (inputStream != null) {
                    responseJson = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
                }
                if (responseJson == null || responseJson.isEmpty()) {
                    LOG.info("json response is null : ");
                    throw new JsonNotFoundException(Constant.JSON_NOT_FOUND);
                }
                sb.append(responseJson);
            } catch (IOException e) {
                LOG.info("IO exception : ");
                throw new IOException(e);
            } catch (Exception e) {
                LOG.info(" exception : ");
                throw new Exception(e);
            }
//        }
//        else{
//            LOG.info("file doesnt exists : "   filePath);
//        }
        return sb.toString();
    }

  

Пример пути к файлу: src/main/resources/data/get-products/1420-17612-82.json
Содержимое файла Docker

 {
  "commands":
  [
    "rm -rf .tmp",
    "git clone git@github.com:{orgnname}/{test-service.git} -b COECP-973-Configure-logging-mechanism-for-Service .tmp/test-service",
    "docker build .tmp/test-service/.docker/build/db -t local/test-service/db",
    "docker build .tmp/test-service -t local/test-service/app"
  ]
}
  

Комментарии:

1. Как вы компилируете и запускаете приложение? Есть ли у контейнера вообще доступ к src ? Даже без Docker обычно Java-приложения компилируются в jar-файлы, исходный код которых отсутствует после их развертывания, и вам приходится загружать ресурсы из classloader, а не из файловой системы.

2. ОК. Они находятся в моем пути к классу после компиляции в / classes / data, и я пытаюсь загрузить их через classloader

3. Итак, я отредактировал свой вопрос и прикрепил полный исходный код

4. Sry /src/main/resources — правильный путь. Кроме того, добавьте содержимое dockerfile в вопрос.

5. да, это /src/main / java /resources

Ответ №1:

Итак … вы перепутали путь для File и для ресурсов из пути к классу. В чем причина иметь File f = new File(filePath); ?

Вот что:

  1. Если вы используете File — файлы должны быть доступны для JVM, и до тех пор, пока вы используете относительный путь, подобный datafolderxxxfilexxx.json , он должен быть доступен в файловой системе контейнера. Т.е. data папка должна быть помещена в образ или смонтирована извне точно в каталог, из которого запускается JVM

  2. Если вы используете, ClassLoader и ResourceAsStream корень вашего data каталога должен быть определен в пути к классу для JVM или находиться в файле Jar — это также корень в classpath. Проверьте свой файл jar — если data каталог находится в корневом каталоге jar — все в порядке, и файлы будут доступны по this.getClass().getClassLoader().getResourceAsStream(filePath) , но не для new File(filePath) !

если нет — сделайте так, чтобы это произошло, или соответствующим образом обновите свой путь к файлу для ResourceAsStream .

Комментарии:

1. Да, это было перепутано с new File (). Я просто удалил его, и это просто сработало

Ответ №2:

Я сталкивался с такой же проблемой ранее, хотя со временем наши требования усложнились, но следующий код должен решить вашу проблему:

     ClassPathResource cp = new ClassPathResource("relative_path_to_file");
    File f = null;

    if (cp.exists())
        f = cp.getFile();
  

Комментарии:

1. Это сработало, я использовал библиотеку ItextPdf, и она ожидает абсолютный путь (не фактический файл). то же самое сделал cp.GetFile().getAbsolutePath().

2. ClassPathResource это специальный библиотечный класс?