2013-07-17 12 views
6

Sto cercando di inviare un oggetto a un attore a distanza ed ho ottenuto questa eccezione:NotSerializableException per `Map [String, String]` alias

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

L'oggetto che viene serializzato è una classe case:

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))))) 
} 

E Attr è un tipo ridefinizione:

type Attr = Map[String, String] 

Il Message la classe è piuttosto semplice:

Mi chiedo se il tipo alias/ridefinizione stia confondendo il serializzatore. Penso di usare la serializzazione ProtoBuf, ma vedo lo JavaSerializer nello stacktrace.

Altre informazioni di debug

ho newed un JavaSerializer e serializzato singolarmente ciascuna delle mappe. Solo uno (alarms) non riesce a serializzare. Ecco il toString di ciascuna di esse:

Questo non è riuscita:

alarms = Map(LOWBATTERY -> 1373623446000) 

Questi sono riusciti:

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

Il tipo di alias non ha assolutamente nulla a che fare con questo. Questo è un problema di runtime e il tipo di alias esiste solo in fase di compilazione. – ghik

+0

Se non sono stati definiti protocolli protobuf per le classi e se ne stanno utilizzando, non si utilizza ProtobufSerialization. –

+0

@ViktorKlang L'ho cambiato in JavaSerialization, non funziona ancora. Penso che abbia a che fare con la serializzazione di 'Map', e come sottolinea @ghik, non è dovuto all'alias. Qualche idea? – kelloti

risposta

26

Il problema è che Map.mapValues produce un oggetto che non è serializzabile. Quando sono stati creati gli allarmi, viene eseguito attraverso qualcosa come alarms.mapValues(hex2Int). Il problema e soluzione è descritta qui:

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

In breve, la soluzione è quella di fare alarms.mapValues(hex2Int).map(identity)

0

Non è sicuro se questo funziona in tutti i casi, ma la mia soluzione era semplicemente quello di convertire la carta in una sequenza (solo .toSeq prima della sequenza) prima della serializzazione. toMap dovrebbe fornire la stessa mappa dopo la deserializzazione.

Problemi correlati