Search code examples
yamlinputstreamjackson-databindjackson-dataformat-yaml

Jackson YAMLParser can't read input stream


I need to process a file from the classpath. The file can be either JSON or YAML. While JSON is processed perfectly fine, YAML does give me some grief. Here is my code:

private Configurator processCofigFile(String cf) throws IOException {
        InputStream configStream;
        ObjectMapper mapper;
        //get configuration from classpath resource
        configStream = this.getClass().getClassLoader().getResourceAsStream(cf);
        if(cf.endsWith("json")) {
            mapper = new ObjectMapper();
        } else if(cf.endsWith("yml") || cf.endsWith("yaml")) {
            mapper = new ObjectMapper(new YAMLFactory());
        } else {
            LOG.error("Unrecognized configuration format");
            throw new IllegalStateException("Unrecognized configuration format");
        }
        return  mapper.readValue(configStream, Configurator.class);
    }

I am getting the following exception:

java.lang.NoSuchMethodError: 'void org.yaml.snakeyaml.parser.ParserImpl.(org.yaml.snakeyaml.reader.StreamReader)' at com.fasterxml.jackson.dataformat.yaml.YAMLParser.<init>(YAMLParser.java:159) at com.fasterxml.jackson.dataformat.yaml.YAMLFactory._createParser(YAMLFactory.java:455) at com.fasterxml.jackson.dataformat.yaml.YAMLFactory.createParser(YAMLFactory.java:357) at com.fasterxml.jackson.dataformat.yaml.YAMLFactory.createParser(YAMLFactory.java:14) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3809)

Looks like SnakeYaml parser does no have a constructor accepting InputStream, only File or Reader. I can create InputStreamReader, but readValue method won't accept it.

I will appreciate any tip on how to make it work.


Solution

  • I did find a solution. Instead of reading resource as a stream I did following:

    File configFile = new File(URLDecoder.decode(this.getClass().getClassLoader().getResource(cf).getFile(), "UTF-8"));
    

    and replaced configStream with configFile in the mapper.