Scala反射:使用protobuf编译akka actor
我正在尝试使用 Scala Reflection Toolbox 编译带有 DynamicMessage 的 Actor
Actor 代码看起来像是
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val toolbox = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val actorCode =
"""
|import akka.actor._
|import com.google.protobuf._
|class SimpleActor extends Actor {
|override def receive: Receive = {
| case dynamicMessage: DynamicMessage => println("Dynamic message received!")
| case _ => println("Whatever!") // the default, catch-all
| }
|}
|object SimpleActor {
|def props() : Props = Props(new SimpleActor())
|}
|
|
|return SimpleActor.props()
|""".stripMargin
val tree = toolbox.parse(actorCode)
toolbox.compile(tree)().asInstanceOf[Props]
出现错误
reflective compilation has failed:
illegal cyclic reference involving type T
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
illegal cyclic reference involving type T
如果我在工具箱之外运行代码,它会编译并正常工作。 该错误是从该行给出的
case dynamicMessage: DynamicMessage => println("Dynamic message received!")
任何人都知道该错误的性质以及如何修复它?
I am trying to compile an Actor with DynamicMessage with Scala Reflection Toolbox
The actor code looks like
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val toolbox = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val actorCode =
"""
|import akka.actor._
|import com.google.protobuf._
|class SimpleActor extends Actor {
|override def receive: Receive = {
| case dynamicMessage: DynamicMessage => println("Dynamic message received!")
| case _ => println("Whatever!") // the default, catch-all
| }
|}
|object SimpleActor {
|def props() : Props = Props(new SimpleActor())
|}
|
|
|return SimpleActor.props()
|""".stripMargin
val tree = toolbox.parse(actorCode)
toolbox.compile(tree)().asInstanceOf[Props]
I get the error
reflective compilation has failed:
illegal cyclic reference involving type T
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
illegal cyclic reference involving type T
If I run the code outside of the Toolbox it compiles and works fine.
The error is given from the line
case dynamicMessage: DynamicMessage => println("Dynamic message received!")
Anyone knows the nature of this error and how to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 Scala 中,即使没有反射编译,也会有 bug 与 scala-java 互操作和 F 边界多态性相结合:
scalac 报告有效 Java 类的错误:涉及类型 T 和其他类型的非法循环引用
。
com.google.protobuf.DynamicMessage
的父母探索 F- bounds:但是如果没有反射编译,您的代码就会编译。所以这是反射编译、scala-java 互操作和 F 边界多态性结合在一起的错误。
解决方法是使用真正的编译器而不是工具箱:
Scala 反射中的 Tensorflow (这里有一个类似的反射编译、Scala-Java 互操作和路径相关类型组合出现错误的情况)
运行时动态编译多个 Scala 类
如何评估代码使用 InterfaceStability 注释(因“涉及类 InterfaceStability 的非法循环引用”而失败)?(反射编译期间也是“非法循环引用”)
Scala 演示编译器 - 最小示例
(*) 运行时生成的协议缓冲区对象
In Scala even without reflective compilation there are bugs in combination of scala-java interop and F-bounded polymorphism:
scalac reports error on valid Java class: illegal cyclic reference involving type T
and others.
And parents of
com.google.protobuf.DynamicMessage
explore F-bounds:But without reflective compilation your code compiles. So this is a bug in combination of reflective compilation, scala-java interop and F-bounded polymorphism.
A workaround is to use real compiler instead of toolbox:
Tensorflow in Scala reflection (here was a similar situation with a bug in combination of reflective compilation, Scala-Java interop, and path-dependent types)
Dynamic compilation of multiple Scala classes at runtime
How to eval code that uses InterfaceStability annotation (that fails with "illegal cyclic reference involving class InterfaceStability")? (also "illegal cyclic reference" during reflective compilation)
Scala Presentation Compiler - Minimal Example
(*) Protocol buffer objects generated at runtime