scala - Chill-kryo 中的异常

标签 scala serialization kryo

我正在尝试从此 link 运行 Chill-Scala 的示例代码

我有两个虚拟案例类

一个是用户

@SerialVersionUID(1)
case class User(name :String, age : Int) extends Serializable 

另一个是学生

@SerialVersionUID(2)
case class Student(sub : String , id : Int , user : User) extends Serializable

这是我从这个 github 示例中修改的序列化代码 twitter/chill repo

object SeriDeseri {
  private val kryo = {
    val a = KryoSerializer.registerAll
    val k = new Kryo
    a(k)
    k
  }

  def toBytes(student : Student): Array[Byte] = {
    println("********** serializing")
    val b = new ByteArrayOutputStream
    val o = new Output(b)
    kryo.writeObject(o, student)
    o.close()
    b.toByteArray
  }

  def fromBytes[Student](bytes: Array[Byte])(implicit m: Manifest[Student]): Option[Student] = {
    println("********** Deserializing")
    val i = new Input(bytes)
    try {
      val t = kryo.readObject(i, m.runtimeClass.asInstanceOf[Class[Student]])
      Option(t)
    } catch {
      case NonFatal(e) => None
    } finally {
      i.close()
    }
  }
}

这是我的主类的代码

val user = new User( "Ahsen", 14)
val stu = new Student("oop", 12, user)

  val serial : Array[Byte] = SeriDeseri.toBytes(stu)
  val deserial :Option[Student] = SeriDeseri.fromBytes(serial)
  val obj  = deserial match{
    case Some(objec) => println(objec)
    case None => println("----------- Nothing was deserialized")
  }

现在的问题是,当我运行这段代码时,它给我 java.lang.InstantiationError: scala.runtime.Nothing$ 异常

这里是完整的堆栈跟踪

[info] Running kryotest.Main

********** serializing

********** Deserializing [error] (run-main-0) java.lang.InstantiationError: scala.runtime.Nothing$ java.lang.InstantiationError: scala.runtime.Nothing$ at scala.runtime.Nothing$ConstructorAccess.newInstance(Unknown Source) at com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy$1.newInstance(Kryo.java:1193) at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1061) at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:547) at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:523) at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:657) at com.test.hcast_serializer.SeriDeseri$.fromBytes(SeriDeseri.scala:32) at kryotest.Main$.delayedEndpoint$kryotest$Main$1(Main.scala:31) at kryotest.Main$delayedInit$body.apply(Main.scala:9) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:76) at scala.App$$anonfun$main$1.apply(App.scala:76) at scala.collection.immutable.List.foreach(List.scala:383) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) at scala.App$class.main(App.scala:76) at kryotest.Main$.main(Main.scala:9) at kryotest.Main.main(Main.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) [trace] Stack trace suppressed: run last compile:run for the full output. java.lang.RuntimeException: Nonzero exit code: 1 at scala.sys.package$.error(package.scala:27) [trace] Stack trace suppressed: run last compile:run for the full output. [error] (compile:run) Nonzero exit code: 1 [error] Total time: 4 s, completed Aug 31, 2015 3:15:54 PM

请告诉我我做错了什么?

编辑:当我从 fromBytes 方法中替换以下行时

val t = kryo.readObject(i, m.runtimeClass.asInstanceOf[Class[Student]])

val t = kryo.readClassAndObject(i).asInstanceOf[Student]

我不太清楚修改后发生了什么,但它没有给我异常,但方法返回了 None 而不是对象

修改后的输出

********** serializing
********** Deserializing
----------- Nothing was deserialized

最佳答案

由于您示例的 git 存储库中示例的第一行说 Chill 现在支持 Scala 2.11。请改用它。

有一种使用 chill from twitter 序列化 Scala 对象的简单方法

这是他们说的:

Chill-bijection

Bijections and Injections are useful when considering serialization. If you have an Injection from T to Array[Byte] you have a serialization. Additionally, if you have a Bijection between A and B, and a serialization for B, then you have a serialization for A. See BijectionEnrichedKryo for easy interop between bijection and chill. KryoInjection: easy serialization to byte Arrays

KryoInjection is an injection from Any to Array[Byte]. To serialize using it:

import com.twitter.chill.KryoInjection

val bytes: Array[Byte] = KryoInjection(someItem) val tryDecode: scala.util.Try[Any] = KryoInjection.invert(bytes)

KryoInjection can be composed with Bijections and Injections from com.twitter.bijection.

所以我重写了你的主类:

object Main extends App {

  val user = new User( "Ahsen", 14)
  val stu = new Student("oop", 12, user)



  val bytes:  Array[Byte]    = KryoInjection(stu)

  println("Serialized byte array:" + bytes)

  val tryDecode: scala.util.Try[Any] = KryoInjection.invert(bytes)

  println(tryDecode)

}

对于你的 build.sbt 使用这个:

"com.twitter" % "chill-bijection_2.11" % "0.7.0"

最后我得到了这个结果:

[info] Running chill.Main 
Serialized byte array:[B@17e5b410
Success(Student(oop,12,User(Ahsen,14)))

关于scala - Chill-kryo 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32309269/

相关文章:

scala - 减少案例类模型的 Slick 定义中的样板

data-structures - 如何从Scala中的文件读取不可变数据结构

scala - 为什么我不能将 Nothing 分配给 Unit 类型的变量?

java - 是 :gen-class is the only way to extend Java class in Clojure?

C:使用序列化数据作为类型

apache-spark - Kryo序列化器如何在Spark中分配缓冲区

scala - Akka Stream - 根据流中的元素选择接收器

php - 序列化一个数组并压缩字符串以在 url 中使用它

java - 序列化并不总是以序列化原始类型结束吗?

java - 使用 Kryo 序列化同步映射