2013-07-17 17 views
6

Próbuję wysłać obiekt do zdalnego aktor i mam ten wyjątek:NotSerializableException dla `Mapa String, String []` alias

ERROR akka.remote.EndpointWriter - Transient association error (association remains live) 
java.io.NotSerializableException: scala.collection.immutable.MapLike$$anon$2 

Obiekt jest w odcinkach jest klasa obudowy:

case class LocationReport(idn: String, report: String, timestamp: Option[String], location: Attr, status: Attr, alarms: Attr, network: Attr, sensors: Attr) extends Message(idn) { 

    val ts = timestamp getOrElse location("fix_timestamp") 

    def json = 
    (report -> 
     ("TIME" -> ts) ~ 
     ("location" -> location) ~ 
     ("alarms" -> alarms) ~ 
     ("network" -> network) ~ 
     ("sensors" -> ((status ++ sensors) + ("CUSTOMCLOCK" -> Report.decodeTimestamp(ts))))) 
} 

I Attr jest typu re-definicja:

type Attr = Map[String, String] 

Message Klasa jest całkiem prosta:

abstract class Message(idn: String) { 
    def topic = idn 
    def json(): JValue 
} 

Zastanawiam się, czy typ/redefinicja mylące serializer. Myślę, że używam serializacji ProtoBuf, ale widzę JavaSerializer w stacktrace.

Więcej debugowanie informacji

I newed górę JavaSerializer i indywidualnie odcinkach każdej z map. Tylko jeden (alarms) nie może serializować. Oto toString każdego z nich:

Ten failed:

alarms = Map(LOWBATTERY -> 1373623446000) 

nich udało:

location = Map(a_value -> 6, latitude -> 37.63473, p_value -> 4, longitude -> -97.41459, fix_timestamp -> 3F0AE7FF, status -> OK, fix_type -> MSBL, CUSTOMCLOCK -> 1373644159000) 
network = Map(SID -> 1271, RSSI -> 85) 
sensors = Map(HUMIDITY -> -999, PRESSURE -> -999, LIGHT -> -999 9:52 AM) 
status = Map(TEMPERATURE_F -> 923, CYCLE -> 4, TEMPERATURE1_C -> 335, CAP_REMAINING -> 560, VOLTAGE -> 3691, CAP_FULL -> 3897) 
+3

Alias ​​typu nie ma absolutnie nic wspólnego z tym. Jest to problem runtime i wpisz aliasy istnieje tylko w czasie kompilacji. – ghik

+0

Jeśli nie zdefiniowałeś protokołów protobuf dla swoich klas i używasz ich, to nie korzystasz z ProtobufSerialization. –

+0

@ViktorKlang Zmieniłem go na JavaSerialization, nadal nie działa. Myślę, że ma to związek z serializacją "Map", a jak wskazuje @ghik, nie jest to spowodowane aliasem. Jakieś pomysły? – kelloti

Odpowiedz

26

Problemem jest to, że Map.mapValues tworzy obiekt, który nie jest możliwy do serializacji. Po utworzeniu alarmów jest uruchamiany przez coś takiego jak alarms.mapValues(hex2Int). Problem i obejście jest opisany tutaj:

https://issues.scala-lang.org/browse/SI-7005

Krótko mówiąc, rozwiązanie to zrobić alarms.mapValues(hex2Int).map(identity)

0

Nie jestem pewien, czy to działa we wszystkich przypadkach, ale mój obejście było po prostu przekonwertować mapę do sekwencji (po prostu .toSeq przed sekwencją) przed serializacją. toMap powinien dać tę samą mapę po deserializacji.

Powiązane problemy