Невозможно прочитать файл ресурсов пути к классам неблокирующим образом внутри контейнера докеров

Я пытаюсь загрузить файл JSON sample.json из каталога src/main/resources.

Мне нужно сопоставить этот json-объект с Java-объектом. И мое приложение реактивное, я использую Spring webflux.

Я следил за блогом Саймона, чтобы придумать следующее:

    SimpleModule module = new SimpleModule();
    module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<>() {
      @Override
      public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return OffsetDateTime.parse(p.getValueAsString());
      }
    });

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(module);


    return Flux.using(() -> Files.lines(Paths.get(ClassLoader.getSystemResource("sample.json").toURI())),
        Flux::fromStream,
        BaseStream::close
    )
        .collectList()
        .map(lines -> String.join("\n", lines))
        .map(jsonContent -> {
          try {
            return objectMapper.readValue(jsonContent, MyPojo.class);
          } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
          }
        })
        .map(MyPojo::getValues());

Это нормально работает в локальном режиме, но не работает при запуске внутри контейнера докеров. (Я использую сборку gradle для создания файла jar, а затем создаю из него образ докера)

Часть трассировки стека ошибок:

java.nio.file.FileSystemNotFoundException: null в jdk.zipfs / jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem (ZipFileSystemProvider.java:169) ~ [jdk.zipfs: na] Подавлено: Reaction.coreFilex


person User12343445    schedule 10.08.2020    source источник
comment
Убедитесь, что связанный ресурс - это ваш путь к классам внутри контейнера Docker. Возможно, вам нужно добавить его в свой Dockerfile: docs.docker.com/engine/reference / builder / # add   -  person Alberto Segura    schedule 10.08.2020
comment
В решении Саймона также используется блокирующий ввод-вывод, поэтому, если у вас нет преимуществ от использования здесь Flux, вы можете просто прочитать файл обычным способом с блокировкой, используя поток ввода, и переложить работу на гибкий планировщик.   -  person Martin Tarjányi    schedule 10.08.2020
comment
Отвечает ли это на ваш вопрос? Реактивный способ чтения и анализа файла из ресурсов с использованием WebFlux?   -  person Martin Tarjányi    schedule 10.08.2020


Ответы (1)


При запуске образа докера вы пытаетесь получить доступ к файлу из Jar. И похоже, что передача URI ресурса напрямую Paths.get не сработает.

Вы можете обратиться к следующим обсуждениям stackoverflow относительно того же:

  1. Этот ответ
  2. Ответы на этот вопрос
  3. Ответы на этот вопрос

Думаю, вам стоит взглянуть на этот класс Spring, который декодирует поток байтов в JSON и преобразует его в объекты с помощью Jackson 2.9, используя неблокирующий синтаксический анализ.

Этот код должен соответствовать вашим потребностям:

Сначала получите ссылку на Resource в Spring

  @Value("classpath:/sample.json")
  Resource sampleFile;

Затем сделайте это:

return new Jackson2JsonDecoder()
        .decodeToMono(
            DataBufferUtils.read(sampleFile, new DefaultDataBufferFactory(), 4096),
            ResolvableType.forClass(MyPojo.class),
            null,
            null)
        .map(object -> (MyPojo) object)
        .map(MyPojo::getValues)

Таким образом, вы можете читать файл неблокирующим образом, используя DataBufferUtils.read, а также сопоставлять json со своим POJO.

person Abhinaba Chakraborty    schedule 10.08.2020