Reputation: 572
I'm trying to use akkas persistance module(2.3.0), unfortunately when I'm sending Persistent message containing Enumeration I'm getting java.io.NotSerializableException
. Here's my earthy example:
object TestEnum extends Enumeration with Serializable {
type TestEnum = Value
val test = Value("test")
}
class TestProcessor extends Processor with Logging {
override def receive: Actor.Receive = {
case PersistenceFailure(payload, sequenceNr, cause) =>
log.error(s"error when reciving persistent message[$payload]", cause)
case a =>
log.error(s"test proc recived message [$a]")
}
}
val a = sys.actorOf(Props[TestProcessor])
a ! Persistent(TestEnum.test)
this ends with
error when reciving persistent message[test]java.io.NotSerializableException: scala.slick.driver.JdbcTypesComponent$MappedJdbcType$$anon$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at akka.serialization.JavaSerializer$$anonfun$toBinary$1.apply$mcV$sp(Serializer.scala:129)
at akka.serialization.JavaSerializer$$anonfun$toBinary$1.apply(Serializer.scala:129)
at akka.serialization.JavaSerializer$$anonfun$toBinary$1.apply(Serializer.scala:129)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
at akka.serialization.JavaSerializer.toBinary(Serializer.scala:129)
at akka.persistence.serialization.MessageSerializer.persistentPayloadBuilder(MessageSerializer.scala:111)
at akka.persistence.serialization.MessageSerializer.akka$persistence$serialization$MessageSerializer$$persistentMessageBuilder(MessageSerializer.scala:97)
at akka.persistence.serialization.MessageSerializer.toBinary(MessageSerializer.scala:45)
at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90)
at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90)
at scala.util.Try$.apply(Try.scala:161)
at akka.serialization.Serialization.serialize(Serialization.scala:90)
at akka.persistence.journal.leveldb.LeveldbStore$class.persistentToBytes(LeveldbStore.scala:98)
at akka.persistence.journal.leveldb.LeveldbJournal.persistentToBytes(LeveldbJournal.scala:19)
at akka.persistence.journal.leveldb.LeveldbStore$class.akka$persistence$journal$leveldb$LeveldbStore$$addToMessageBatch(LeveldbStore.scala:104)
at akka.persistence.journal.leveldb.LeveldbStore$$anonfun$writeMessages$1$$anonfun$apply$1.apply(LeveldbStore.scala:48)
at akka.persistence.journal.leveldb.LeveldbStore$$anonfun$writeMessages$1$$anonfun$apply$1.apply(LeveldbStore.scala:48)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at akka.persistence.journal.leveldb.LeveldbStore$$anonfun$writeMessages$1.apply(LeveldbStore.scala:48)
at akka.persistence.journal.leveldb.LeveldbStore$$anonfun$writeMessages$1.apply(LeveldbStore.scala:48)
at akka.persistence.journal.leveldb.LeveldbStore$class.withBatch(LeveldbStore.scala:90)
at akka.persistence.journal.leveldb.LeveldbJournal.withBatch(LeveldbJournal.scala:19)
at akka.persistence.journal.leveldb.LeveldbStore$class.writeMessages(LeveldbStore.scala:48)
at akka.persistence.journal.leveldb.LeveldbJournal.writeMessages(LeveldbJournal.scala:19)
at akka.persistence.journal.SyncWriteJournal$$anonfun$receive$1$$anonfun$1.apply$mcV$sp(SyncWriteJournal.scala:27)
at akka.persistence.journal.SyncWriteJournal$$anonfun$receive$1$$anonfun$1.apply(SyncWriteJournal.scala:27)
at akka.persistence.journal.SyncWriteJournal$$anonfun$receive$1$$anonfun$1.apply(SyncWriteJournal.scala:27)
at scala.util.Try$.apply(Try.scala:161)
at akka.persistence.journal.SyncWriteJournal$$anonfun$receive$1.applyOrElse(SyncWriteJournal.scala:27)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at akka.persistence.journal.leveldb.LeveldbJournal.aroundReceive(LeveldbJournal.scala:19)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
at akka.dispatch.Mailbox.run(Mailbox.scala:220)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
anybody has any idea what is going on here and how to fix it?
Upvotes: 3
Views: 1184
Reputation: 572
It was more complicated that I thought. According to Patrik suggesstion I've defined all participating objects as top level classes/objects in different files. And test example started to work. Finally I've discovered why error occurs:
I'm using slick to communicate with my DB so I've declared very useful Enumeration base class with default mapper that allows slick to use Enumeration without writing converters
abstract class DBEnum extends Enumeration {
implicit val enumMapper = MappedJdbcType.base[Value, String](_.toString, this.withName(_))
}
Then I've derived from that class and created
object AccountType extends DBEnum{
type AccountType = Value
val ADMINISTRATOR = Value("administrator")
val REGULAR = Value("regular")
val ADMINISTRATOR_SPONSORED = Value("administrator_sponsored")
}
my actual test example was
a ! Persistent(TestEnum.test)
a ! Persistent(AccountType.ADMINISTRATOR)
and it seems that TestEnum started to have enumMapper(probably because of some weird implicit conversion - maby someone can explain how is it possible) which can't be serialized(it does not implement serializable).
changing
implicit val enumMapper = MappedJdbcType.base[Value, String](_.toString, this.withName(_))
to
implicit def enumMapper = MappedJdbcType.base[Value, String](_.toString, this.withName(_))
fixed my problem.
Upvotes: 2