【问题标题】:Exception in Chill-kryoChill-kryo 中的例外
【发布时间】:2015-11-25 08:54:40
【问题描述】:

我正在尝试从 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()
    }
  }
}

这是我的 Main 类的代码

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$ 异常

这里是完整的堆栈跟踪

[信息] 运行 kryotest.Main

********** 序列化

********** 反序列化 [错误] (run-main-0) java.lang.InstantiationError: scala.runtime.Nothing$ java.lang.InstantiationError: scala.runtime.Nothing$ at scala.runtime.Nothing$ConstructorAccess.newInstance(未知来源) 在 com.esotericsoftware.kryo.Kryo$DefaultInstantiatorStrategy$1.newInstance(Kryo.java:1193) 在 com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1061) 在 com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:547) 在 com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:523) 在 com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:657) 在 com.test.hcast_serializer.SeriDeseri$.fromBytes(SeriDeseri.scala:32) 在 kryotest.Main$.delayedEndpoint$kryotest$Main$1(Main.scala:31) 在 kryotest.Main$delayedInit$body.apply(Main.scala:9) 在 scala.Function0$class.apply$mcV$sp(Function0.scala:40) 在 scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 在 scala.App$$anonfun$main$1.apply(App.scala:76) 在 scala.App$$anonfun$main$1.apply(App.scala:76) 在 scala.collection.immutable.List.foreach(List.scala:383) 在 scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) 在 scala.App$class.main(App.scala:76) 在 kryotest.Main$.main(Main.scala:9) 在 kryotest.Main.main(Main.scala) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:497) [trace] 堆栈 跟踪抑制:运行最后一次编译:运行完整输出。 java.lang.RuntimeException:非零退出代码:1 at scala.sys.package$.error(package.scala:27​​) [trace] 堆栈跟踪 抑制:运行最后一次编译:运行完整输出。 [错误] (compile:run) Nonzero exit code: 1 [error] Total time: 4 s, completed 2015 年 8 月 31 日下午 3:15:54

请告诉我我做错了什么?

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

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

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

我不完全知道修改后发生了什么,但它没有给我异常,但方法返回 None 而不是对象

修改后的输出

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

【问题讨论】:

    标签: scala serialization kryo


    【解决方案1】:

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

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

    他们是这样说的:

    冷双射

    双射和注入在考虑序列化时很有用。 如果你有一个从 T 到 Array[Byte] 的注入,你有一个 序列化。此外,如果您在 A 和 B 之间存在双射, 和 B 的序列化,然后你有 A 的序列化。见 BijectionEnrichedKryo 用于在双射和寒意之间轻松互操作。 KryoInjection:轻松序列化为字节数组

    KryoInjection 是从 Any 到 Array[Byte] 的注入。序列化 使用它:

    导入 com.twitter.chill.KryoInjection

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

    KryoInjection 可以由 Bijections 和 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)))
    

    【讨论】:

    • 我还想问一件事,序列化程序是否需要是一个对象? toBytes 和 fromBytes 方法是静态的吗?或者我们可以在简单的类中使用它们?
    • KryoInjection 是一个 scala 对象,在这种情况下你使用方法 invert 和 apply,这是 Twitter 在 github 上建议的方式,看看类实现github.com/twitter/chill/blob/…跨度>
    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多