Was about to post this as an issue on GitHub, but I saw the note encouraging discussion here before opening issues, so here we are. =)
My understanding of the problem is this: when de-serializing JSON, the memoization logic which maps classes to constructors in net.liftweb.json.Meta ignores type parameters. If a parameterized type is used multiple times during extraction, subsequent lookups for the same (erased) type will return the original constructor, even if different parameters were provided. The following code highlights the issue - the second call to 'read' tries to construct an instance of TypeA instead of TypeB, and throws an exception when it can't find the field 'foo':
import net.liftweb.json.Serialization.read import net.liftweb.json.DefaultFormats object JsonParseTest extends App { implicit val formats = DefaultFormats val jsonA = """ { "data": { "foo": "string" }, "success": true } """ println(read[Container[TypeA]](jsonA)) val jsonB = """ { "data": { "bar": "string" }, "success": true } """ println(read[Container[TypeB]](jsonB)) } case class TypeA(foo: String) case class TypeB(bar: String) case class Container[D](data: D)And the output:
Container(TypeA(string)) Exception in thread "main" net.liftweb.json.MappingException: No usable value for data No usable value for foo
Issue created: lift/framework/issues/1417. Thanks Joni.- Justin