Issues while deserializing exception/throwable using Jackson in Java -


i facing issues while deserializing exception , throwable instances using jackson (version 2.2.1). consider following snippet:

public static void main(string[] args) throws ioexception {     objectmapper objectmapper = new objectmapper();     objectmapper.configure(serializationfeature.indent_output, true);     objectmapper.setvisibility(propertyaccessor.field, visibility.any);     objectmapper.enabledefaulttyping(defaulttyping.non_final, as.property);      try {         integer.parseint("string");     }     catch (numberformatexception e) {         runtimeexception runtimeexception = new runtimeexception(e);         string serializedexception = objectmapper.writevalueasstring(runtimeexception);         system.out.println(serializedexception);         throwable throwable = objectmapper.readvalue(serializedexception, throwable.class);         throwable.printstacktrace();     } } 

the output of system.out.println in catch block is:

{   "@class" : "java.lang.runtimeexception",   "detailmessage" : "java.lang.numberformatexception: input string: \"string\"",   "cause" : {     "@class" : "java.lang.numberformatexception",     "detailmessage" : "for input string: \"string\"",     "cause" : null,     "stacktrace" : [ {       "declaringclass" : "java.lang.numberformatexception",       "methodname" : "forinputstring",       "filename" : "numberformatexception.java",       "linenumber" : 65     }, {       "declaringclass" : "java.lang.integer",       "methodname" : "parseint",       "filename" : "integer.java",       "linenumber" : 492     }, {       "declaringclass" : "java.lang.integer",       "methodname" : "parseint",       "filename" : "integer.java",       "linenumber" : 527     }, {       "declaringclass" : "test.jackson.jacksontest",       "methodname" : "main",       "filename" : "jacksontest.java",       "linenumber" : 26     } ],     "suppressedexceptions" : [ "java.util.arraylist", [ ] ]   },   "stacktrace" : [ {     "declaringclass" : "test.jackson.jacksontest",     "methodname" : "main",     "filename" : "jacksontest.java",     "linenumber" : 29   } ],   "suppressedexceptions" : [ "java.util.arraylist", [ ] ] } 

which seems fine. when attempt deserialize using objectmapper.readvalue(), following exception:

exception in thread "main" com.fasterxml.jackson.databind.exc.unrecognizedpropertyexception: unrecognized field "declaringclass" (class java.lang.stacktraceelement), not marked ignorable  @ [source: java.io.stringreader@3c5ebd39; line: 9, column: 27] (through reference chain: java.lang.stacktraceelement["declaringclass"])     @ com.fasterxml.jackson.databind.exc.unrecognizedpropertyexception.from(unrecognizedpropertyexception.java:79)     @ com.fasterxml.jackson.databind.deserializationcontext.reportunknownproperty(deserializationcontext.java:555)     @ com.fasterxml.jackson.databind.deser.std.stddeserializer.handleunknownproperty(stddeserializer.java:708)     @ com.fasterxml.jackson.databind.deser.std.jdkdeserializers$stacktraceelementdeserializer.deserialize(jdkdeserializers.java:414)     @ com.fasterxml.jackson.databind.deser.std.jdkdeserializers$stacktraceelementdeserializer.deserialize(jdkdeserializers.java:380)     @ com.fasterxml.jackson.databind.deser.std.objectarraydeserializer.deserialize(objectarraydeserializer.java:151) ... 

i tried using mix-in annotations, ignore declaringclass in java.lang.stacktraceelement, deserialized exception doesn't contain declaring class in stack trace:

java.lang.runtimeexception: java.lang.numberformatexception: input string: "string"     @ .main(jacksontest.java:33) caused by: java.lang.numberformatexception: input string: "string"     @ .forinputstring(numberformatexception.java:65)     @ .parseint(integer.java:492)     @ .parseint(integer.java:527)     @ .main(jacksontest.java:30) 

am missing anything? appreciated.

there seems jackson jira entry here. jackson doesn't seem able handle declaringclass in java.lang.stacktraceelement, since getter corresponding field called getclassname().

i fixed issue using custom wrapper around stacktraceelement suggested in jira entry mentioned above. custom wrapper (customstacktraceelement) have fields declaringclass, methodname, filename, , linenumber , corresponding getters , setters in it. modified catch block (mentioned in question) follows:

catch (numberformatexception e) {     runtimeexception runtimeexception = new runtimeexception(e);     e.printstacktrace();     string serializedexception = objectmapper.writevalueasstring(runtimeexception);     system.out.println(serializedexception);      string serializedstacktrace = objectmapper.writevalueasstring(transformstacktrace(runtimeexception));     string serializedstacktraceforcause = objectmapper.writevalueasstring(transformstacktrace(runtimeexception.getcause()));      throwable throwable = objectmapper.readvalue(serializedexception, throwable.class);     list<customstacktraceelement> customstacktraceelementlist = objectmapper.readvalue(serializedstacktrace, list.class);     list<customstacktraceelement> customstacktraceelementlistforcause = objectmapper.readvalue(serializedstacktraceforcause, list.class);      throwable.setstacktrace(reversetransformstacktrace(customstacktraceelementlist));     throwable.getcause().setstacktrace(reversetransformstacktrace(customstacktraceelementlistforcause));     throwable.printstacktrace(); } 

the stacktraceelement[] converted list<customstacktraceelement> following method during serialization:

private static list<customstacktraceelement> transformstacktrace(throwable throwable) {     list<customstacktraceelement> list = new arraylist<>();     (stacktraceelement stacktraceelement : throwable.getstacktrace()) {         customstacktraceelement customstacktraceelement =             new customstacktraceelement(stacktraceelement.getclassname(),                                         stacktraceelement.getmethodname(),                                         stacktraceelement.getfilename(),                                         stacktraceelement.getlinenumber());          list.add(customstacktraceelement);     }      return list; } 

... , reverse transformation done during deserialization:

private static stacktraceelement[] reversetransformstacktrace(list<customstacktraceelement> customstacktraceelementlist) {     stacktraceelement[] stacktraceelementarray = new stacktraceelement[customstacktraceelementlist.size()];     (int = 0; < customstacktraceelementlist.size(); i++) {         customstacktraceelement customstacktraceelement = customstacktraceelementlist.get(i);         stacktraceelement stacktraceelement =             new stacktraceelement(customstacktraceelement.getdeclaringclass(),                                   customstacktraceelement.getmethodname(),                                   customstacktraceelement.getfilename(),                                   customstacktraceelement.getlinenumber());          stacktraceelementarray[i] = stacktraceelement;     }      return stacktraceelementarray; } 

now, after deserialization, throwable object has expected stack trace in it.


Comments

Popular posts from this blog

curl - PHP fsockopen help required -

HTTP/1.0 407 Proxy Authentication Required PHP -

c# - Resource not found error -