как использовать Scala Maps с akka-kryo-сериализатором - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь использовать библиотеку akka-kryo-serializer.

Мне удается заставить его работать со строкой в ​​качестве теста, но затем, когда я использую тот же код для работы с картой, тщательно следуя инструкциям веб-сайта, у меня возникают те же ошибки:

Error1: Я следую инструкциям на сайте и пишу:

package entellect.spike.Kryo

import java.io.{ByteArrayInputStream, ByteArrayOutputStream}

import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.{Input, Output}


object KryoSpike extends App {

  val kryo = new Kryo()
  kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaMapSerializer])
  kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaMapSerializer])

  val testin = Map("id" -> "objID", "field1" -> "field1Value")

  val outStream = new ByteArrayOutputStream()
  val output = new Output(outStream, 4096)
  kryo.writeClassAndObject(output, testin)
  output.flush()


  val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
  val testout = kryo.readObject(input, classOf[Map[String,String]])

  println(testout.toString)

}

Этот код не компилируется из-за следующих двух строк, взятых с сайта:

kryo.addDefaultSerializer (classOf [scala.collection.Map [, ]], classOf [ScalaMapSerializer]) kryo.addDefaultSerializer (classOf [scala.collection.generic.MapFactory [scala.collection.Map]], classOf [ScalaMapSerializer])

Я стараюсь следить за тем, что находится в тесте веб-сайта. Для тестирования карты используется:

kryo.setRegistrationRequired (правда) kryo.addDefaultSerializer (classOf [scala.collection.Map [_, _]], classOf [ScalaImmutableMapSerializer]) kryo.register (classOf [scala.collection.immutable.HashMap $ HashTrieMap], 40)

Следующая строка не компилируется, потому что компиляция не находит "HashMap $ HashTrieMap"

classOf[ScalaImmutableMapSerializer])
    kryo.register(classOf[scala.collection.immutable.HashMap$HashTrieMap],

40)

Наконец мой пример выглядит так:

пакет entellect.spike.Kryo

import java.io. {ByteArrayInputStream, ByteArrayOutputStream}

импорт com.esotericsoftware.kryo.Kryo import com.esotericsoftware.kryo.io. {Вход, Выход} import com.romix.scala.serialization.kryo.ScalaImmutableMapSerializer

object KryoSpike extends App {

  val kryo = new Kryo()
  kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaImmutableMapSerializer])
  kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaImmutableMapSerializer])

  val testin = Map("id" -> "objID", "field1" -> "field1Value")

  val outStream = new ByteArrayOutputStream()
  val output = new Output(outStream, 4096)
  kryo.writeClassAndObject(output, testin)
  output.flush()


  val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
  val testout = kryo.readObject(input, classOf[Map[String,String]])

  println(testout.toString)

}

Но тогда я получаю следующую ошибку:

Исключение в теме "основной" com.esotericsoftware.kryo.KryoException: Класс не может быть создан (отсутствует конструктор без аргументов): scala.collection.immutable.Map на com.esotericsoftware.kryo.Kryo $ DefaultInstantiatorStrategy.newInstantiatorOf (Kryo.java:1319) в com.esotericsoftware.kryo.Kryo.newInstantiator (Kryo.java:1127) в com.esotericsoftware.kryo.Kryo.newInstance (Kryo.java:1136) в com.romix.scala.serialization.kryo.ScalaImmutableMapSerializer.read (ScalaMapSerializers.scala: 75) в com.romix.scala.serialization.kryo.ScalaImmutableMapSerializer.read (ScalaMapSerializers.scala: 69) в com.esotericsoftware.kryo.Kryo.readObject (Kryo.java:709) в entellect.spike.Kryo.KryoSpike $ .delayedEndpoint $ entellect $ шип $ Kryo $ KryoSpike $ 1 (KryoSpike.scala: 25) в entellect.spike.Kryo.KryoSpike $ delayedInit $ body.apply (KryoSpike.scala: 10) в scala.Function0 $ class.apply $ mcV $ sp (Function0.scala: 34) в scala.runtime.AbstractFunction0.apply $ мкВ $ зр (AbstractFunction0.scala: 12) в scala.App $$ anonfun $ main $ 1.применить (App.scala: 76) в scala.App $$ anonfun $ main $ 1.apply (App.scala: 76) в scala.collection.immutable.List.foreach (List.scala: 392) в scala.collection.generic.TraversableForwarder $ class.foreach (TraversableForwarder.scala: 35) в scala.App $ class.main (App.scala: 76) в entellect.spike.Kryo.KryoSpike $ .main (KryoSpike.scala: 10) в entellect.spike.Kryo.KryoSpike.main (KryoSpike.scala)

EDIT1:

Моя зависимость

  "org.apache.spark" % "spark-core_2.11" % "2.3.1",
  "org.apache.spark" % "spark-sql_2.11" % "2.3.1",
  "com.typesafe.akka" %% "akka-stream" % "2.5.16",
  "com.typesafe.akka" %% "akka-http-spray-json" % "10.1.4",
  "com.typesafe.akka" %% "akka-stream-kafka" % "0.22",
  "com.github.romix.akka" %% "akka-kryo-serialization" % "0.5.0"

Обратите внимание, что я не использую особую функцию Kkao Akka, я использую ее как универсальную платформу сериализации. То же самое с искрой. Нет прямого подключения к свече или конфигурации акки.

1 Ответ

0 голосов
/ 14 сентября 2018

Решение использует

ScalaImmutableAbstractMapSerializer с Map

и методом writeObject && readObject.

package entellect.spike.Kryo

import java.io.{ByteArrayInputStream, ByteArrayOutputStream}

import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.{Input, Output}
import com.romix.scala.serialization.kryo._

object KryoSpike extends App {


  val kryo = new Kryo()
  kryo.setRegistrationRequired(false)
  kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaImmutableAbstractMapSerializer])
  kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaImmutableAbstractMapSerializer])

  val testin = Map("id" -> "objID", "field1" -> "field1Value")

  val outStream = new ByteArrayOutputStream()
  val output = new Output(outStream, 4096)
  kryo.writeObject(output, testin)
  output.flush()


  val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
  val testout = kryo.readObject(input, classOf[scala.collection.Map[_,_]])

  println(testout.toString)

}
...