2016-11-25 71 views
2

下面的代碼在操作數棧壞類型:java.lang.VerifyError的:使用Scala的泡椒

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 = [email protected] 

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。這是可以實現的嗎?斯卡拉2.11.8。

+0

這可能只是一個錯誤,並由一些宏的廢話造成的。無論如何,你的問題不是很清楚。你想僅僅使用Pickling來(去)序列化'Message'類型嗎?或更復雜的東西?你真的需要'FastTypeTag'嗎? – laughedelic

+0

問題鏈接:https://github.com/scala/pickling/issues/445 –

回答

1

如果您改變implicit object申報到VAL

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

一切都很好地工作。由於@laughedelic comment提到,這可能是由於宏和初始化之間的一些有趣的交互。

經Scala 2.11.8和Scala Pickling 0.10.1測試。

+1

吃那個賞金和感謝! – Dyin

+0

不幸的是,當你創建'class messageSerializer extends Serializer [Message]'時,你會得到同樣的錯誤。 – Dyin

+0

如果你改變序列化爲'def serialize(data:T)(隱式p:Pickler [T],f:FastTypeTag [T]):Array [Byte] = ...' –