Как я могу загрузить свой файл YAML в класс case?

У меня есть приложение Scala, которому нужно прочитать файл Yaml и загрузить его в класс case Scala. Я использую змею для выполнения этой работы, но кажется, что функция загрузки не может использовать конструктор моего класса case. Ниже приведен пример того, что я делаю:

Ямл-файл:

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

Класс корпуса:

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

Код для извлечения и загрузки 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]

Я получаю следующую ошибку:

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

Что я могу сделать, чтобы избавиться от ошибки?


person Need Answers Fast    schedule 18.09.2018    source источник


Ответы (1)


По-видимому, ошибка связана с тем, что Snakeyaml пытается вызвать конструктор без аргументов, а затем установить все свойства с помощью сеттеров.

Это никогда не будет работать со Scala case class, потому что у них нет ни конструктора без аргументов, ни сеттеров. Источник.

В качестве обходного пути вы можете использовать circe-yaml.

person Luis Miguel Mejía Suárez    schedule 19.09.2018
comment
Это решение сработало для меня. Я использовал синтаксический анализатор circe для преобразования YAML в объект Json. Оттуда я преобразовал Json в строку, чтобы я мог использовать методы отражения Json4s для сопоставления значений с классами case. - person Need Answers Fast; 19.09.2018
comment
@NeedAnswersFast Я рад, что это сработало для вас. Но я думаю, что вы совершаете долгое путешествие... Circe предоставляет способ превратить Jsons в кейс-классы. Это позволяет избежать использования другой библиотеки, а также накладных расходов на преобразование Json в строку для повторного анализа для создания класса case. - person Luis Miguel Mejía Suárez; 20.09.2018
comment
Да, ты прав. Я могу предоставить Circe правильный Decoder для преобразования YAML в мои классы case. Я, вероятно, сделаю это в будущем, но поскольку мое приложение уже использует Json4s отражение для многих классов case, это потребует серьезного рефакторинга. - person Need Answers Fast; 20.09.2018