2

I am trying to load a JSON file sample.json from src/main/resources directory.

I have to map that json to a Java Object. And my application is reactive, I am using Spring webflux.

I have followed Simon's Blog to come up with this:

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

This works fine in local but fails when running inside a docker container. (I am using gradle build to build the jar file and then build the docker image from it)

Part of the error stacktrace:

java.nio.file.FileSystemNotFoundException: null at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:169) ~[jdk.zipfs:na] Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:

3

1 Answer 1

3

When running the docker image, you are trying to access the file from inside a Jar. And it seems that passing a resource URI directly to Paths.get won't work.

You can refer to the following stackoverflow discussions regarding the same:

  1. This answer
  2. Answers to this question
  3. Answers to this question

I think you should take a look at this class of Spring which decodes a byte stream into JSON and convert to Object's with Jackson 2.9, leveraging non-blocking parsing.

This code should serve your needs:

First get reference to the Resource in Spring's way

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

Then do this:

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

In this way, you can read the file in a non-blocking manner using DataBufferUtils.read and also map the json to your POJO.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.