i use jackson scala module.
i've created little serialization tool handle json payloads received play2 framework.
def unserializepayloadas[t](implicit requestcontext: requestcontext[jsvalue]): t = { val json: string = json.stringify(requestcontext.request.body) unserialize(json) } def unserialize[t](json: string): t = { objectmapper.readvalue(json) }
the readvalue of jackson scala module has signature:
def readvalue[t: manifest](content: string): t = { readvalue(content, constructtype[t]) }
when trying use deserialization code, have stack.
caused by: com.fasterxml.jackson.databind.jsonmappingexception: can not instantiate abstract type [simple type, class scala.runtime.nothing$] (need add/enable type information?) @ [source: java.io.stringreader@7bb78579; line: 1, column: 2] @ com.fasterxml.jackson.databind.jsonmappingexception.from(jsonmappingexception.java:164) ~[jackson-databind-2.2.0.jar:2.2.0] @ com.fasterxml.jackson.databind.deser.std.throwabledeserializer.deserializefromobject(throwabledeserializer.java:77) ~[jackson-databind-2.2.0.jar:2.2.0] @ com.fasterxml.jackson.databind.deser.beandeserializer.deserialize(beandeserializer.java:121) ~[jackson-databind-2.2.0.jar:2.2.0] @ com.fasterxml.jackson.databind.objectmapper._readmapandclose(objectmapper.java:2888) ~[jackson-databind-2.2.0.jar:2.2.0] @ com.fasterxml.jackson.databind.objectmapper.readvalue(objectmapper.java:2041) ~[jackson-databind-2.2.0.jar:2.2.0] @ com.fasterxml.jackson.module.scala.experimental.scalaobjectmapper$class.readvalue(scalaobjectmapper.scala:157) ~[jackson-module-scala_2.10-2.2.0.jar:2.2.0] @ utils.customserializer$$anon$1.readvalue(customserializer.scala:17) ~[na:na] @ utils.customserializer$.unserialize(customserializer.scala:39) ~[na:na] @ utils.customserializer$.unserializepayloadas(customserializer.scala:35) ~[na:na]
as expected, works fine when add manifest in code:
def unserializepayloadas[t: manifest](implicit requestcontext: requestcontext[jsvalue]): t = { val json: string = json.stringify(requestcontext.request.body) unserialize(json) } def unserialize[t: manifest](json: string): t = { objectmapper.readvalue(json) }
can explain happens there? when call method manifest
context bound, parametrized method no manifest
, manifest of nothing
provided first method?
i have expected kind of compilation error, telling me i'm calling readvalue
parametrized type has no manifest
or that, seems more fail-fast.
take simpler example:
def getmanifest[a: manifest] = implicitly[manifest[a]]
or equivalent desugared version:
def getmanifest[a](implicit whatever: manifest[a]) = whatever
and then:
scala> def getit[t]: manifest[t] = getmanifest <console>:8: error: type mismatch; found : manifest[nothing] required: manifest[t] note: nothing <: t, trait manifest invariant in type t. may wish investigate wildcard type such `_ <: t`. (sls 3.2.10) def getit[t]: manifest[t] = getmanifest ^
what's happening when compiler tries infer type parameter getmanifest
, there lots of types have manifest
instances in scope, , has no way choose between them, goes default choice, nothing
.
(you're seeing error @ runtime instead of compile-time because, well, that's happens when use reflection-based approaches serialization.)
we can add context bound:
def getit[t: manifest]: manifest[t] = getmanifest
or, equivalently:
def getit[t](implicit whatever: manifest[t]): manifest[t] = getmanifest
now fine—there's single precise manifest
instance in scope, compiler can (appropriately) resolve type parameter getmanifest
t
.
you can see little more dramatically in following example:
scala> trait foo[a] defined trait foo scala> def getfoo[a: foo] = implicitly[foo[a]] getfoo: [a](implicit evidence$1: foo[a])foo[a] scala> implicit object stringfoo extends foo[string] defined module stringfoo scala> def getit[t]: foo[t] = getfoo <console>:10: error: type mismatch; found : foo[string] required: foo[t] def getit[t]: foo[t] = getfoo ^
since there's 1 foo
instance in scope (for string
), compiler can pick when it's resolving type parameter getfoo
, , end different type mismatch.
Comments
Post a Comment