REST Jackson JsonDeserialize, StackOverflowError after update

In a previous version of jackson (1.9.2), the following code worked fine:

import org.codehaus.jackson.map.JsonDeserializer; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.DeserializationContext; ... @JsonDeserialize(using = RoleDeserializer.class) public interface RoleDto {} public class RoleDeserializer extends SomeSharedDeserializer<RoleDto> {} public class SomeSharedDeserializer<T> extends JsonDeserializer<T> { @Override public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { return jp.readValueAs(getImplementation()); } public Class<? extends T> getImplementation(){ ... returns some generated implementation of RoleDto } } 

After we switched to the latest version of Jackson (1.9.13 provided by Wildfly 8.2), we got an exception:

com.fasterxml.jackson.databind.JsonMappingException: cannot create an instance of RoleDto, problem: abstract types either have to map to specific types, have a custom deserializer, or create additional type information

Well, as with the new jackson packages, we updated them to:

 import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer; 

Now the deserializer is visible (there is no previous exception), however we get a StackOverflowError exception. The file com.fasterxml.jackson.databind.ObjectMapper reads the value (line 3023):

  DeserializationContext ctxt = createDeserializationContext(jp, cfg); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType); // ok, let get the value if (cfg.useRootWrapping()) { result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); } else { result = deser.deserialize(jp, ctxt); } 

We pass to the line: result = deser.deserialize(jp, ctxt);

As a result, it raises an infinite loop and a StackOverflowError.

One of the recommended methods is to implement our own SomeSharedDeserializer as:

 ObjectCodec oc = jp.getCodec(); JsonNode node = oc.readTree(jp); //here manually create new object and return it 

But our classes are generated. As another solution, I tried using

 ObjectMapper mapper = new ObjectMapper(); mapper.readValue(jp, getImplementation()); 

But got the same result - StackOverflow exception.

How can we fix this? Is it possible to use some deserializer to pass its instance of JsonParser, a generated class that implements the base interface without StackOverflowError?

+5
source share
1 answer

Here you can find a full description and tests to find a solution. The following solution was found:

 import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig; import com.fasterxml.jackson.databind.deser.BeanDeserializerFactory; import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; import com.fasterxml.jackson.databind.type.SimpleType; ... public abstract class RestDtoDeserializer<T> extends JsonDeserializer<T> { @Override public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { DeserializationConfig config = ctxt.getConfig(); SimpleType simpleType = SimpleType.construct(getImplementationClass()); BeanDescription beanDesc = config.introspect(simpleType); BeanDeserializerFactory instance = new BeanDeserializerFactory(new DeserializerFactoryConfig()); JsonDeserializer deserializer = instance.buildBeanDeserializer(ctxt, simpleType, beanDesc); ((ResolvableDeserializer)deserializer).resolve(ctxt); return (T) deserializer.deserialize(jp, ctxt); } public abstract Class<? extends T> getImplementationClass(); 
+1
source

Source: https://habr.com/ru/post/1211762/


All Articles