HazelcastSerializationException с Kryo с использованием Scala

Я использую kryo для сериализации со Scala 2.11.1 и Hzaelcast 3.5. Я пытаюсь поместить свои данные в карту hazelcast, но получаю KryoException

вот мой модельный класс

  @SerialVersionUID(1)
        case class User( id : Int ,name : String, userType : UserType /*UserType is Enum (EMPLOYED , UNEMPLOYED)*/ , userhistory : UserHistory) extends  Serializable{

def this()= {
this(0,"",Active, null)
}
}

вот UserHistory класс

    @SerialVersionUID(1)
case  class UserHistory( date : DateTime = DateTime.now(), artworkStatus : ArtworkStatus = ACTIVE) extends  Serializable{

def this()={
    this(DateTime.parse("0"),ACTIVE) 
  }
}

вот мой сериализатор для класса User

class UserSerializer extends StreamSerializer[User] {


   val log = LoggerFactory.getLogger(this.getClass)

   override def destroy() {

  }

  override def getTypeId() : Int ={
    val value : Int = 1;
    value

  }

  // takes the bytes and converts into User Object
   @throws(classOf[IOException])
  override def read(in : ObjectDataInput) : User =  {

     val kryo = new Kryo 
     val input = new Input(in.asInstanceOf[InputStream])
      log.info("********** Reading the bytes and converting into User object")
     kryo.readClassAndObject(input).asInstanceOf[User]



  }

   // takes User Object and converts into bytes
  @throws(classOf[IOException])
  override def write(out : ObjectDataOutput, obj : User) {

    val kryo= new Kryo
    val bops = new ByteArrayOutputStream
    val output = new Output(bops)
    kryo.writeClassAndObject(output , obj)
    output.flush
    output.close

    bops.writeTo(out.asInstanceOf[OutputStream])

    log.info("********** User object writen into bytes successfully")


  }


}

теперь, когда я помещаю объект класса User из клиента Hcast в соответствующую карту, подобную этой

map.set(user.id , user)

это дает мне это исключение:

 Cannot invoke the action, eventually got an error: com.hazelcast.nio.serialization.HazelcastSerializationException: com.esotericsoftware.kryo.KryoException: Class cannot be created (non-static member class): scala.Enumeration$Val

Завершить StackTraces из Hcast Client :

7:52:25.094 152121 [play-akka.actor.default-dispatcher-2] UserSerializer INFO - ********** Пользовательский объект успешно записан в байты 17:52:29.667 156694 [play-akka.actor .default-dispatcher-2] play ERROR — не удается вызвать действие, в итоге возникла ошибка: com.hazelcast.nio.serialization.HazelcastSerializationException: com.esotericsoftware.kryo.KryoException: класс не может быть создан (нестатический класс-член): scala.Enumeration$Val Трассировка сериализации: userType (UserHistory) UserHistory (User) 17:52:29.832 156859 [play-akka.actor.default-dispatcher-2] ОШИБКА приложения -

! @ 6nb1hbglj - Внутренняя ошибка сервера для (POST) [/user/signup] ->

play.api.Application$$anon$1: исключение выполнения[[HazelcastSerializationException: com.esotericsoftware.kryo.KryoException: класс не может быть создан (нестатический класс-член): scala.Enumeration$Val Трассировка сериализации: userType (UserHistory) UserHistory ( Пользователь) в play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.8.jar:2.3.8] в play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.8.jar:2.3.8] в play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3 .8.jar:2.3.8] в play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.8.jar:2.3 .8]

ниже приведены StackTraces из Hcast Server

17:52:28.010 [hz._hzInstance

  @SerialVersionUID(1)
        case class User( id : Int ,name : String, userType : UserType /*UserType is Enum (EMPLOYED , UNEMPLOYED)*/ , userhistory : UserHistory) extends  Serializable{

def this()= {
this(0,"",Active, null)
}
}
dev.partition-operation.thread-0] ИНФОРМАЦИЯ models.serializers.UserSerializer - ********** Чтение байтов и преобразование в объект пользователя 17:52:28.990 [hz ._hzInstance
  @SerialVersionUID(1)
        case class User( id : Int ,name : String, userType : UserType /*UserType is Enum (EMPLOYED , UNEMPLOYED)*/ , userhistory : UserHistory) extends  Serializable{

def this()= {
this(0,"",Active, null)
}
}
dev.partition-operation.thread-0] ОШИБКА chmap.impl.operation.SetOperation - [192.168.15.20]:5701 [dev] [3.5] com.esotericsoftware.kryo.KryoException: класс не может быть создан (нестатический класс-член): scala.Enumeration$Val Трассировка сериализации: userType (UserHistory) UserHistory (User) com.hazelcast.nio.serialization.HazelcastSerializationException: com.esotericsoftware.kryo.KryoException: класс не может быть создан (нестатический класс-член): scala.Enumeration$Val Трассировка сериализации: userType (UserHistory) UserHistory (User) в com.hazelcast.nio.serialization.SerializationServiceImpl.handleException(SerializationServiceImpl.java:380) ~[hazelcast-3.5.jar:3.5] в com.hazelcast. nio.serialization.SerializationServiceImpl.toObject(Сериализация onServiceImpl.java:282) ~[hazelcast-3.5.jar:3.5] в com.hazelcast.map.impl.mapstore.AbstractMapDataStore.toObject(AbstractMapDataStore.java:78) ~[hazelcast-3.5.jar:3.5] в com. hazelcast.map.impl.mapstore.writethrough.WriteThroughStore.add(WriteThroughStore.java:39) ~[hazelcast-3.5.jar:3.5] в com.hazelcast.map.impl.mapstore.writethrough.WriteThroughStore.add(WriteThroughStore.java :31) ~[hazelcast-3.5.jar:3.5] в com.hazelcast.map.impl.DefaultRecordStore.set(DefaultRecordStore.java:803) ~[hazelcast-3.5.jar:3.5] в com.hazelcast.map.impl .operation.SetOperation.run(SetOperation.java:41) ~[hazelcast-3.5.jar:3.5] в com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:137) ~[hazelcast- 3.5.jar:3.5] в com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.processOperation(OperationThread.java:154) [hazelcast-3.5.jar:3.5] в com.hazelcast.spi.impl.operationexecutor.class ic.OperationThread.process(OperationThread.java:110) [hazelcast-3.5.jar:3.5] в com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.doRun(OperationThread.java:101) [hazelcast-3.5.jar :3.5] at com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.run(OperationThread.java:76) [hazelcast-3.5.jar:3.5] Причина: com.esotericsoftware.kryo.KryoException: невозможно создать класс (нестатический класс-член): scala.Enumeration$Val

Пожалуйста, помогите мне!!


person M.Ahsen Taqi    schedule 01.09.2015    source источник


Ответы (2)


Обычно со Scala вы должны использовать StdInstantiatorStrategy, например.

val kryo = new Kryo
val is = new org.objenesis.strategy.StdInstantiatorStrategy
kryo.setInstantiatorStrategy(instantiatorStrategy)

Не уверен, что это решит вашу проблему, но я не видел таких проблем.

person nilskp    schedule 04.09.2015
comment
Отлично работает и для Java - person Dekel; 11.03.2020

Вы зарегистрировали сериализатор enum, как указано на github?

        // Serialization of Scala enumerations
        kryo.addDefaultSerializer(classOf[scala.Enumeration#Value], classOf[EnumerationSerializer])
        kryo.register(Class.forName("scala.Enumeration$Val"))
        kryo.register(classOf[scala.Enumeration#Value])

Исключение довольно ясно, что оно не может создать userType, которое является перечислением.

com.esotericsoftware.kryo.KryoException: Class cannot be created (non-static member class): scala.Enumeration$Val Serialization trace: userType (UserHistory) UserHistory (User)
person Fatih Donmez    schedule 01.09.2015
comment
Должен ли я написать сериализатор отдельно для моего перечисления (EnumerationSerializer в вашем решении)? - person M.Ahsen Taqi; 02.09.2015
comment
Я не эксперт в библиотеке kryo, но сериализатор Enum по умолчанию должен подойти для вашего пользовательского перечисления UserType, просто явно зарегистрируйте его, как в ответе. - person Fatih Donmez; 02.09.2015