Java 无法在docker容器内以非阻塞方式读取类路径资源文件

Java 无法在docker容器内以非阻塞方式读取类路径资源文件,java,spring-boot,jackson,spring-webflux,project-reactor,Java,Spring Boot,Jackson,Spring Webflux,Project Reactor,我试图从src/main/resources目录加载一个JSON文件sample.JSON 我必须将json映射到Java对象。我的应用程序是被动的,我使用的是SpringWebFlux 我随后得出了以下结论: SimpleModule module = new SimpleModule(); module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<>() { @Override

我试图从
src/main/resources
目录加载一个JSON文件sample.JSON

我必须将json映射到Java对象。我的应用程序是被动的,我使用的是SpringWebFlux

我随后得出了以下结论:

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

SimpleModule=newsimpleModule();
module.addDeserializer(OffsetDateTime.class,新的JsonDeserializer()){
@凌驾
public OffsetDateTime反序列化(JsonParser p,DeserializationContext ctxt)抛出IOException,JsonProcessingException{
返回OffsetDateTime.parse(p.getValueAsString());
}
});
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.registerModule(模块);
返回Flux.using(()->Files.lines(path.get(ClassLoader.getSystemResource(“sample.json”).tori()),
通量::fromStream,
BaseStream::关闭
)
.LIST()
.map(行->字符串.join(“\n”,行))
.map(jsonContent->{
试一试{
返回objectMapper.readValue(jsonContent,MyPojo.class);
}捕获(JsonProcessingException e){
e、 printStackTrace();
返回null;
}
})
.map(MyPojo::getValues());
这在本地运行良好,但在docker容器中运行时失败。(我正在使用gradle build构建jar文件,然后从中构建docker映像)

错误跟踪的一部分:

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


运行docker映像时,您试图从Jar内部访问该文件。而且似乎将资源URI直接传递给
路径.get
将不起作用

您可以参考以下与此相关的stackoverflow讨论:

  • 这个
  • 答案
  • 答案
  • 我认为您应该看看Spring,它利用非阻塞解析将字节流解码为JSON,并使用Jackson 2.9转换为对象

    此代码应满足您的需要:

    首先以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。

    检查wnated资源是否是Docker容器中的类路径。也许你必须将它添加到Dockerfile中:Simon的解决方案也使用阻塞I/O,因此如果你在这里使用Flux没有任何好处,那么你可以使用inputstream以常规阻塞方式读取文件,并将工作卸载到弹性调度程序。这是否回答了你的问题?