Search code examples
javadeserializationyamlyamlbeans

yamlbeans: why is a scalar for String type expected?


Introduction

I'm attempting to deserialize the contents of a YAML document into a Java object using yamlbeans (v1.0). Here's the YAML document which I'm trying to deserialize (topologyGrammar.yml):

---
rules: 
  - !tp.aoi.topology.TopologyRule { labels: ["empty_A"], output: ["entry_B"] }

Here's how I attempt the deserialization:

mainTG = (TopologyGrammar) loadYAML(TopologyGrammar.class, "grammars/topologyGrammar.yml");

where loadYAML looks like the following:

public Object loadYAML(Class<?> daClass, String URL) throws YamlException {
    FileHandle handle = Gdx.files.internal(URL);
    YamlConfig config = new YamlConfig();
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    config.readConfig.setClassLoader(classLoader);
    YamlReader reader = new YamlReader(handle.reader(), config);
    return reader.read(daClass);
} 

This method hasn't had problems loading other YAML files I've tried. I get the following at the top of my stack trace:

net.sourceforge.yamlbeans.YamlReader$YamlReaderException: Line 8, column 7: Expected scalar for String type but found: sequence start
at net.sourceforge.yamlbeans.YamlReader.readValueInternal(YamlReader.java:175)
at net.sourceforge.yamlbeans.YamlReader.readValue(YamlReader.java:150)
at net.sourceforge.yamlbeans.YamlReader.readValueInternal(YamlReader.java:261)
at net.sourceforge.yamlbeans.YamlReader.readValue(YamlReader.java:150)
at net.sourceforge.yamlbeans.YamlReader.readValueInternal(YamlReader.java:298)
at net.sourceforge.yamlbeans.YamlReader.readValue(YamlReader.java:150)
at net.sourceforge.yamlbeans.YamlReader.readValueInternal(YamlReader.java:261)
at net.sourceforge.yamlbeans.YamlReader.readValue(YamlReader.java:150)
at net.sourceforge.yamlbeans.YamlReader.read(YamlReader.java:106)
at net.sourceforge.yamlbeans.YamlReader.read(YamlReader.java:91)
at tp.aoi.grammars.YAMLparser.loadYAML(YAMLparser.java:69)
at tp.aoi.grammars.YAMLparser.<init>(YAMLparser.java:43)
...

The reference to YAMLparser.java:43 refers to the deserialization line I pasted above.

Class Definitions

Here's my definition for TopologyGrammar.java:

public class TopologyGrammar {
    public List<TopologyRule> rules;
}

And my definition for TopologyRule.java:

public class TopologyRule {
    public List<String> labels;
    public List<String> output;
}

Additional Thoughts

It looks to me that the Expected scalar for String type but found: sequence start is referring to the labels: ["empty_A"] part of the document. What I'm really wondering about is why would the YamlReader be expecting a String anyway when I say that labels is a List<String> (and should therefore be represented as a sequence in the document)?

Question

For what reason would YamlReader expect a string and not a List<String>?

I'm hoping that my problem isn't specific to the yamlbeans project. It seems to me that this is simply an error in how my YAML syntax relates to my class definitions.


Solution

  • It appears that YamlBeans 1.09 doesn't handle all of features in the YAML 1.2 spec, and this may have been the cause of the issue here.

    I've since switched to the SnakeYaml Library and found it to a major improvement in many respects, and it deserializes the document properly.