Search code examples
javascalareflectioncase-classsnakeyaml

How can I load my YAML file into a case class?


I have a Scala application that needs to read in a Yaml file and load it into a Scala case class. I'm using snakeyaml to do the job, but it seems that the load function can't use my case class's constructor. The following is an example of what I'm doing:

Yaml File:

name: "Jon"
age: 50
gender: "male"

Case Class:

final case class Person(
    name: String, 
    age: Int,
    gender: String
)

Code to extract and load YAML:

val text: String = scala.io.Source.fromFile(file).mkString
val yaml = new Yaml(new Constructor(implicitly[ClassTag[T]].runtimeClass))
yaml.load(text).asInstanceOf[T]

I get the following error:

 org.yaml.snakeyaml.constructor.ConstructorException: Can't construct a java object for tag:yaml.org,2002:case_classes.Person; exception=java.lang.InstantiationException: NoSuchMethodException:case_classes.Person.<init>()

What can I do, to get rid of the error?


Solution

  • Apparently the error is because Snakeyaml attempts to call the no-args constructor and then set all properties using setters.

    That will never work with a Scala case class, beacuse they neither have a no-args constructor nor setters. Source.

    For a workaround you can use circe-yaml.