spray / spray-json

A lightweight, clean and simple JSON implementation in Scala
Apache License 2.0
974 stars 190 forks source link

A default Map[Int,X] format is available at compile time, but fails at runtime #125

Open acruise opened 9 years ago

acruise commented 9 years ago
scala> import spray.json._
scala> import spray.json.DefaultJsonProtocol._
scala> val jf = implicitly[JsonFormat[Map[Int,String]]]
jf: spray.json.JsonFormat[Map[Int,String]] = spray.json.CollectionFormats$$anon$3@2de7fe0e

scala> jf.write(Map(1 -> "Foo"))
spray.json.SerializationException: Map key must be formatted as JsString, not '1'
  at spray.json.CollectionFormats$$anon$3$$anonfun$write$3.apply(CollectionFormats.scala:53)
  at spray.json.CollectionFormats$$anon$3$$anonfun$write$3.apply(CollectionFormats.scala:50)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.immutable.Map$Map1.foreach(Map.scala:116)
  at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
  at scala.collection.AbstractTraversable.map(Traversable.scala:104)
  at spray.json.CollectionFormats$$anon$3.write(CollectionFormats.scala:50)
  at spray.json.CollectionFormats$$anon$3.write(CollectionFormats.scala:48)
  ... 35 elided

scala> jf.read("""{"2": "Two"}""".parseJson)
spray.json.DeserializationException: Expected Int as JsNumber, but got "2"
  at spray.json.package$.deserializationError(package.scala:23)
  at spray.json.BasicFormats$IntJsonFormat$.read(BasicFormats.scala:29)
  at spray.json.BasicFormats$IntJsonFormat$.read(BasicFormats.scala:25)
  at spray.json.JsValue.convertTo(JsValue.scala:31)
  at spray.json.CollectionFormats$$anon$3$$anonfun$read$3.apply(CollectionFormats.scala:59)
  at spray.json.CollectionFormats$$anon$3$$anonfun$read$3.apply(CollectionFormats.scala:58)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
  at scala.collection.immutable.Map$Map1.foreach(Map.scala:116)
  at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
  at scala.collection.AbstractTraversable.map(Traversable.scala:104)
  at spray.json.CollectionFormats$$anon$3.read(CollectionFormats.scala:60)
  at spray.json.CollectionFormats$$anon$3.read(CollectionFormats.scala:48)
  ... 35 elided
sirthias commented 9 years ago

Yes, thanks for the report!

acruise commented 9 years ago

Presumably the same applies to any old AnyVal... Using a Long as a key will be extremely common too. :)

maciejjaskowski commented 9 years ago

This is not a bug, this is JSON: http://json.org/

acruise commented 9 years ago

@maciejjaskowski, the bug is that Spray will find a format at compile time that cannot possibly succeed at runtime. :)

initialcontext commented 9 years ago

Any movement on this? I have encountered the same issue with spray-json_2.10 v1.3.2 when serializing or deserializing maps with non-String keys

minisaw commented 9 years ago

so annoying not being able to serialize non-String keyed maps.

kardapoltsev commented 9 years ago

+1

hopkirk commented 9 years ago

+1

blbarker commented 8 years ago

+1

ppiotrow commented 8 years ago

+1

wlk commented 8 years ago

I stumbled on the same bug just now, this is my approach to reproduce: https://github.com/wlk/spray-serialization-bug/blob/master/src/main/scala/Main.scala

fmarmann commented 8 years ago

+1

satyagraha commented 7 years ago

If I copy the code from https://github.com/ancane/spray-json/commit/0b6c60030c169fabbae9fe434fd23d0506944abd into my source and have it visible at implicit resolution time, then it gets picked up OK. If using IntelliJ I found I had to rebuild my entire project as it seems to cache stuff.

janjaali commented 4 years ago

I just tried to resolve the issue and improve the extensibility of the Map format https://github.com/spray/spray-json/pull/331. It would be kind if you would take a look at it :)