java.lang.VerifyError:使用Scala Pickle在操作数堆栈上的错误类型

时间:2016-11-25 12:21:16

标签: scala serialization pickler

以下代码:

import scala.pickling.{FastTypeTag, Pickler, Unpickler}
import scala.pickling.binary._
import scala.pickling.Defaults._

class Serializer[T : Pickler : FastTypeTag] {
  def serialize(data: T): Array[Byte] = {
    Foo.bar(data)
  }
}

object Foo {
  def bar[T: Pickler: FastTypeTag](t: T): Array[Byte] = t.pickle.value
  def unbar[T: Unpickler: FastTypeTag](bytes: Array[Byte]): T = bytes.unpickle[T]
}

class Message(message: String)

implicit object messageSerializer extends Serializer[Message]

def test[A: Pickler: FastTypeTag: Serializer](message: A): Array[Byte] = {
  implicitly[Serializer[A]].serialize(message)
}

val message = new Message("message")

test(message)

评估为:

import scala.pickling.{FastTypeTag, Pickler, Unpickler}
import scala.pickling.binary._
import scala.pickling.Defaults._

defined class Serializer





defined module Foo




defined class Message

defined module messageSerializer

test: test[A](val message: A)(implicit <synthetic> val evidence$10: scala.pickling.Pickler[A],implicit <synthetic> val evidence$11: pickling.FastTypeTag[A],implicit <synthetic> val evidence$12: Serializer[A]) => Array[Byte]



message: Message = com.impresign.hub.core.A$A12$A$A12$Message@6c7df044

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    com/impresign/hub/core/A$A12$A$A12$messageSerializer$.<init>(Lcom/impresign/hub/core/A$A12$A$A12;)V @212: invokespecial
  Reason:
    Type uninitializedThis (current frame, stack[3]) is not assignable to 'com/impresign/hub/core/A$A12$A$A12$messageSerializer$'
  Current Frame:
    bci: @212
    flags: { flagThisUninit }
    locals: { uninitializedThis, 'com/impresign/hub/core/A$A12$A$A12', 'scala/runtime/VolatileObjectRef', 'scala/Tuple2' }
    stack: { uninitializedThis, 'com/impresign/hub/core/A$A12$A$A12', 'scala/Predef$', uninitializedThis, 'scala/runtime/VolatileObjectRef', 'com/impresign/hub/core/A$A12$A$A12' }
  Bytecode:
    0x0000000: 2a2b b200 2db8 0031 4db2 0036 b600 3ab9
    0x0000010: 0040 0100 b900 4601 0099 00c5 bb00 4859
    0x0000020: b200 36b6 003a b900 4001 00b2 004d 124f
    0x0000030: b200 54b6 0058 b900 5e01 00b9 0062 0200
    0x0000040: b200 36b6 003a b900 4001 00b2 004d 124f
    0x0000050: b200 54b6 0058 b900 5e01 00b9 0065 0200
    0x0000060: b700 684e 2dc6 006c 2db6 006c c000 6e3a
    0x0000070: 042d b600 71c0 006e 3a05 1904 c100 7399
    0x0000080: 0052 1904 c000 733a 0619 06b6 0076 c000
    0x0000090: 783a 0719 05c1 0073 9900 3919 05c0 0073
    0x00000a0: 3a08 1908 b600 76c0 007a 3a09 1907 1909
    0x00000b0: 3a0a 59c7 000c 5719 0ac6 000e a700 1519
    0x00000c0: 0ab6 0080 9900 0d19 07c0 0082 3a0b a700
    0x00000d0: 0b2a 2c2b b700 843a 0b19 0ba7 0009 2a2c
    0x00000e0: 2bb7 0084 b600 88c0 0078 b200 4d12 4fb2
    0x00000f0: 0054 b600 58b7 008b b1                 
  Stackmap Table:
    full_frame(@191,{UninitializedThis,Object[#147],Object[#10],Object[#72],Object[#110],Object[#110],Object[#115],Object[#120],Object[#115],Object[#122],Object[#122]},{UninitializedThis,Object[#147],Object[#41],Object[#120]})
    full_frame(@199,{UninitializedThis,Object[#147],Object[#10],Object[#72],Object[#110],Object[#110],Object[#115],Object[#120],Object[#115],Object[#122],Object[#122]},{UninitializedThis,Object[#147],Object[#41]})
    full_frame(@209,{UninitializedThis,Object[#147],Object[#10],Object[#72]},{UninitializedThis,Object[#147],Object[#41]})
    full_frame(@217,{UninitializedThis,Object[#147],Object[#10],Object[#72],Top,Top,Top,Top,Top,Top,Top,Object[#130]},{UninitializedThis,Object[#147],Object[#41]})
    full_frame(@222,{UninitializedThis,Object[#147],Object[#10]},{UninitializedThis,Object[#147],Object[#41]})
    full_frame(@228,{UninitializedThis,Object[#147],Object[#10]},{UninitializedThis,Object[#147],Object[#41],Object[#130]})
Output exceeds cutoff limit.

从未见过这样的东西。我想在Scala Pickler 0.10下使用隐式Serializer s。这可以实现吗? Scala 2.11.8。

1 个答案:

答案 0 :(得分:1)

如果您将implicit object声明更改为val

implicit val mssgSerializer: Serializer[Message] = new Serializer[Message]

一切都很好。正如@laughedelic comment所提到的,这可能是由于宏与object初始化之间的一些有趣的交互。

使用Scala 2.11.8和Scala Pickling 0.10.1进行测试。