Search code examples
configurationjava-8yamlsnakeyaml

Get SnakeYAML to serialize object hierarchy properly


I have the following SnakeYAML-based code (v1.17):

public abstract class Beverage {
    protected int quantityOunces;

    // Getters, setters, ctors, etc.
}

public class AlcoholicBeverage extends Beverage {
    protected Double alcoholByVolume;

    // Getters, setters, ctors, etc.
}

public class SnakeTest {
    public static void main(String[] args) {
        new SnakeTest().serialize();
    }

    void serialize() {
        AlcoholicBeverage alcBev = new AlcoholicBeverage(20, 7.5);

        String alcYml = "/Users/myuser/tmp/alcohol.yml";

        FileWriter alcWriter = new FileWriter(alcYml);

        Yaml yaml = new Yaml();

        yaml.dump(alcBev, alcWriter);
    }
}

Which produces the following /Users/myuser/tmp/alcohol.yml file:

!!me.myapp.model.AlcoholicBeverage {}

I would have expected the file's contents to be something like:

quantityOunces: 20
alcoholByVolume: 7.5

So I ask:

  • How do I get the yaml.dump(...) to properly serialize object properties into the file?; and
  • That !!me.myapp.model.AlcoholicBeverage {} metadata is annoying...anyway to configure Yaml to ignore/omit it?

Solution

  • You can obtain the required output by modifying your code as follows:

    SnakeTest.java

    import java.io.FileWriter;
    import java.io.IOException;
    
    import org.yaml.snakeyaml.Yaml;
    
    abstract class Beverage {
        protected int quantityOunces;
    
        public int getQuantityOunces() {
            return quantityOunces;
        }
    
        public void setQuantityOunces(int quantityOunces) {
            this.quantityOunces = quantityOunces;
        }
    
    }
    
    class AlcoholicBeverage extends Beverage {
        protected Double alcoholByVolume;
    
        public AlcoholicBeverage(int quatityOnces, double alcoholByVolume) {
            this.quantityOunces = quatityOnces;
            this.alcoholByVolume = alcoholByVolume;
        }
    
        public Double getAlcoholByVolume() {
            return alcoholByVolume;
        }
    
        public void setAlcoholByVolume(Double alcoholByVolume) {
            this.alcoholByVolume = alcoholByVolume;
        }
    
    }
    
    public class SnakeTest {
        public static void main(String[] args) throws IOException {
            new SnakeTest().serialize();
        }
    
        void serialize() throws IOException {
            AlcoholicBeverage alcBev = new AlcoholicBeverage(20, 7.5);
    
            String alcYml = "/Users/myuser/tmp/alcohol.yml";
    
            Yaml yaml = new Yaml();
            try (FileWriter alcWriter = new FileWriter(alcYml)) {
                alcWriter.write(yaml.dumpAsMap(alcBev));
            }
    
        }
    }
    

    The code has been included in a maven project with the following pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>SnakeYAML</groupId>
      <artifactId>SnakeYAML</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <dependencies>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.17</version>
        </dependency>
      </dependencies>
    </project>
    

    output is:

    alcoholByVolume: 7.5
    quantityOunces: 20