Lift-json generates error "No information known about type"

147 views
Skip to first unread message

scool...@gmail.com

unread,
Apr 6, 2016, 11:09:49 AM4/6/16
to Lift
hello,

consider following piece of Scala code:

import net.liftweb.json._
case class Event(time: Long, genericProperties: Map[String, Object])
object JSONParseTest extends App {
  implicit val formats = DefaultFormats
  val json = parse(
    """
  {
    "time": 1451385000123,
    "genericProperties": {
      "ID": "test"
    }
  }
  """
  )
  def event = json.extract[Event]
  println(event)
}

This generates following error:

Caused by: net.liftweb.json.MappingException: No information known about type
 at net.liftweb.json.Meta$.fail(Meta.scala:191)
 at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:256)
 at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
 at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
 at net.liftweb.json.Extraction$$anonfun$net$liftweb$json$Extraction$$build$1$5.apply(Extraction.scala:328)
 at net.liftweb.json.Extraction$$anonfun$net$liftweb$json$Extraction$$build$1$5.apply(Extraction.scala:328)
 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
 at scala.collection.immutable.List.foreach(List.scala:318)
 at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
 at scala.collection.AbstractTraversable.map(Traversable.scala:105)
 at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:328)
 at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
 ... 31 more


I don't want to change the type of the Map to a more specific type because it can contain several datatypes and I also don't want to use JObject in my Map. How can I do this?
Thanks in advance for your help,

Steven

Peter Petersson

unread,
Apr 6, 2016, 12:36:26 PM4/6/16
to lif...@googlegroups.com
How about using JValue as in

case class Event(time: Long, genericProperties: Map[String, JValue])

best regards Peter Petersson
--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Antonio Salazar Cardozo

unread,
Apr 6, 2016, 2:41:59 PM4/6/16
to Lift
I believe including type hints will do the trick. You'll need to
do something like:

implicit val formats = DefaultFormats + FullTypeHints(classOf[String], classOf[...], ...)

This should, when serializing strings or anything else listed in the
type hints, serialize them with their class alongside the object. The
result should be that they deserialize correctly.

That said, I've never tried to use type hints with String or other
primitives. Not 100% sure that will work.
Thanks,
Antonio

scool...@gmail.com

unread,
Apr 8, 2016, 3:41:36 AM4/8/16
to Lift
Thx for your feedback, Peter.
I prefer not to use any lift-json specific classes in my Map so I'll try the other solution.

best regards,

Steven

Op woensdag 6 april 2016 18:36:26 UTC+2 schreef Peter Petersson:

scool...@gmail.com

unread,
Apr 8, 2016, 3:43:57 AM4/8/16
to Lift
hello Antonio,

this could indeed help when I use lift-json serialisation but I only use it for deserialization so there will be no hints in the json itself. Is there any other way to 'hint' the deserialization process?

kind regards,

Steven

Op woensdag 6 april 2016 20:41:59 UTC+2 schreef Antonio Salazar Cardozo:

Antonio Salazar Cardozo

unread,
Apr 9, 2016, 11:20:26 AM4/9/16
to Lift
You'll have to use a custom serializer:

  class EventSerializer extends CustomSerializer[Event](format => (
    {
      case eventObject: JObject =>
        implicit val formats = DefaultFormats
        val time = (eventObject \ "time").extract[Long]
        val properties = (eventObject \ "genericProperties").asInstanceOf[JObject].values
  
        Event(time, properties)
    },
    {
      case event =>
        implicit val formats = DefaultFormats
        // getting this back to JSON could get hairy, not sure
        decompose(event)
    }
  ))

  implicit val formats = DefaultFormats + new EventSerializer

lift-json already keeps track of things in a `Map[String,Any]`.

However, note that this is a `Map[String,Any]`, not `Map[String,Object]`! That's
the correct Scala type for what you're calling Object… But if you need Object,
you may be able to get away with just casting to Map[String,Object] with no
additional work.
Thanks,
Antonio

Reply all
Reply to author
Forward
0 new messages