簡體   English   中英

Kryo無法序列化java.sql.Timestamp?

[英]Kryo cannot serialize a java.sql.Timestamp?

編輯:使用Kryo 1.04

我現在正在序列化一個Scala中包含java.sql.Timestamp字段的User類。 由於某些原因,Kryo無法找到零參數構造函數並引發錯誤:

Caused by: com.esotericsoftware.kryo.SerializationException: Class cannot be created (missing no-arg constructor): java.sql.Timestamp
Serialization trace:
created (com.threetierlogic.AccountService.models.User)
        at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:688)
        at com.esotericsoftware.kryo.Serializer.newInstance(Serializer.java:75)
        at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:200)
        at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:220)
        at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:200)
        at com.esotericsoftware.kryo.Serializer.readObject(Serializer.java:61)
        at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:589)
        ... 84 more
Caused by: java.lang.InstantiationException: java.sql.Timestamp
        at java.lang.Class.newInstance0(Class.java:340)
        at java.lang.Class.newInstance(Class.java:308)
        at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:676)
        ... 90 more

這是為Riak轉換域對象的轉換器類的一部分。 這是我的轉換器類:

/**
 * Kryo converter for passing domain objects into Riak
 */
class UserConverter(val bucket: String) extends Converter[User] {

  def fromDomain(domainObject: User, vclock: VClock): IRiakObject = {
    val key = domainObject.guid

    if(key == null) throw new NoKeySpecifedException(domainObject)

    val kryo = new Kryo()
    kryo.register(classOf[User])
    kryo.register(classOf[Timestamp])

    val ob = new ObjectBuffer(kryo)
    val value = ob.writeObject(domainObject)

    RiakObjectBuilder.newBuilder(bucket, key)
        .withValue(value)
        .withVClock(vclock)
        .withContentType(Constants.CTYPE_OCTET_STREAM)
        .build()
  }

  def toDomain(riakObject: IRiakObject): User = {
    if(riakObject == null) null

    val kryo = new Kryo()
    kryo.register(classOf[User])
    kryo.register(classOf[Timestamp])
    val ob = new ObjectBuffer(kryo)

    ob.readObject(riakObject.getValue(), classOf[User])
  }
}

我是否需要擴展Timestamp並創建零參數構造函數? 還是有更好的解決方法?

如果我需要升級到2.20,那么在不寫入文件的情況下ObjectBuffer的替代品是什么?

快速瀏覽Kryo主頁表明,在沒有零參數構造函數的情況下,您可以創建Kryo所謂的“實例化策略”來處理該類。 查看“對象創建”部分。

您可以執行以下操作:

  class KryoSO {
    import com.esotericsoftware.kryo.KryoSerializable
    import de.javakaffee.kryoserializers.KryoReflectionFactorySupport
    import com.esotericsoftware.kryo.Kryo
    import com.esotericsoftware.kryo.Serializer
    import java.io.{ InputStream, OutputStream }
    import com.esotericsoftware.kryo.io.{ Output, Input }
    import java.sql.Timestamp

    object TimestampSerializer extends Serializer[Timestamp] {
      override def write(kryo: Kryo, output: Output, t: Timestamp): Unit = {
        output.writeLong(t.getTime(), true);
      }

      override def read(kryo: Kryo, input: Input, t: Class[Timestamp]): Timestamp = {
        new Timestamp(input.readLong(true));
      }

      override def copy(kryo: Kryo, original: Timestamp): Timestamp = {
        new Timestamp(original.getTime());
      }
    }
    val kryo: Kryo = new KryoReflectionFactorySupport
    kryo.addDefaultSerializer(classOf[Timestamp], TimestampSerializer)

    def serialize(o: Any, os: OutputStream) = {
      val output = new Output(os);
      this.kryo.writeClassAndObject(output, o);
      output.flush();
    }

    def deserialize(is: InputStream): Any = {
      kryo.readClassAndObject(new Input(is));
    }

  }
  val k = new KryoSO
  val b = new java.io.ByteArrayOutputStream
  val timestamp = new java.sql.Timestamp(System.currentTimeMillis())

  k.serialize(timestamp, b)

  val result = k.deserialize(new java.io.ByteArrayInputStream(b.toByteArray()))

  println(timestamp)
  println(result.getClass)
  println(result.isInstanceOf[java.sql.Timestamp])
  println(timestamp == result)

結果:

2013-02-07 10:59:19.482
class java.sql.Timestamp
true
true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM