当我试图在案例类中添加新字段时,为什么Ficus抛出异常



我的应用程序使用"typesafe.config"解析设置,然后使用"ficus"将Config对象转换为case类的实例。case类目前有19个构造函数参数。一切正常。然而,当我在"settings.conf"中添加一个新的参数和一个新对应的字段时,我会得到以下异常:

An exception or error caused a run to abort: MyCaseClass.<init>(Ljava/lang/String;Lscala/Option;Lscala/Option;IZLscala/collection/Seq;Ljava/lang/String;ILscala/concurrent/duration/FiniteDuration;ZLscala/Option;Lscala/Option;ILscala/Option;Lscala/concurrent/duration/FiniteDuration;Ljava/lang/String;Ljava/lang/String;II)V 
java.lang.NoSuchMethodError: MyCaseClass.<init>(Ljava/lang/String;Lscala/Option;Lscala/Option;IZLscala/collection/Seq;Ljava/lang/String;ILscala/concurrent/duration/FiniteDuration;ZLscala/Option;Lscala/Option;ILscala/Option;Lscala/concurrent/duration/FiniteDuration;Ljava/lang/String;Ljava/lang/String;II)V

我可以看到"typesafe.config"正在正确地将我的新字段解析为Config对象。但菲库斯随后抛出了这个例外。新字段和新case类构造函数参数的名称应该完全相同。

你知道为什么会发生这种情况吗?

具体问题记录在以下提交中:

1)https://github.com/ceilican/Scorex/commit/133157a6ad070cad7a57624c511ee917133ed5f1

2)https://github.com/ceilican/Scorex/commit/074e0bc5add3c666b0943497a5579f3fd365084d

3)https://github.com/ceilican/Scorex/commit/7c8d3475377a17b2a5383bf3a99d797650ca8bc3

前两个提交正在工作。对于第三个,会抛出上面提到的异常。

正如您所看到的,提交2和提交3在概念上没有太大区别。我不明白为什么提交2有效,而提交3无效。

有一段时间,我认为这可能是因为case类中有大量的参数,但下面的提交表明,当我将新字段添加到一个较小的case类时,问题也会发生:

4)https://github.com/ceilican/Scorex/commit/1c253b2b526db1539fa674069232cf02784c4bfb

当我尝试在提交4之后运行代码时,也会引发同样的异常。

这是菲库斯的虫子吗?

在主项目和子项目上执行sbt clean后,问题停止发生。我的猜测是Ficus的宏魔术基于我的case类生成函数,但当case类被修改时,它们不会重新生成。然后,当Ficus试图使用与新case类不兼容的过时函数时,就会抛出异常。

有趣的是,只有当我修改"嵌套"的case类时,才会出现缺乏重新生成的情况。如果配置文件是:

main {
nested {
param: 0
}
}

案例类别:

case class MainCaseClass(nested: NestedCaseClass)
case class NestedCaseClass(param: Int)

那么,修改MainCaseClass不会引起问题,但修改NestedCaseClass会引起问题。

最新更新