3
votes

I am trying to run the sample code for Chill-Scala from this link

I have two dummy case classes

one is User

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

and the other is Student

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

here is my code for serialization that i have modified from this github example 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()
    }
  }
}

here is the code for my Main class

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")
  }

Now the problem is when i run this code it gives me java.lang.InstantiationError: scala.runtime.Nothing$ exception

here are complete stack traces

[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

Please tell me what am i doing wrong?

Edit: when i replaced the following line from fromBytes method

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

with

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

i dont excatly know what happened after the modification but it did not give me the exception but the method returned None instead of the object

output after the modification

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

1 Answers

2
votes

Since the first line of the example in the git repository for your example say Chill now supports Scala 2.11. Please use it instead.

There is an easy way of serializing scala objects using chill from twitter

here is what they said:

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.

So I rewrite your main class:

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)

}

and for your build.sbt use this:

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

And finally I get this result:

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