Limit Jackson Serialization/Deserialization Depth for all the class - java

I have tried CustomJSONSerializer from
Suppress wrapper object when serializing Java object into JSON using Jackson.
But getting following exception:
com.fasterxml.jackson.databind.JsonMappingException: object is not an instance of declaring class (through reference chain: com.fasterxml.jackson.databind.type.SimpleType["test"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:183)
I want to serialize entity Like
Entity A
Entity A.Parent
Entity A.Parent.Parent

I got this error too when switching from jackson 2.1.5 to 2.2.0 (or 2.2.1), try downgrading jackson to 2.1.5? Assume it's due to stricter checks in 2.2, but haven't figured out yet how to correct it.

Related

Error when using mockito.mock(<SomeObject>.class) and object mapper

Im getting an InvalidDefinitionException when I try to map a mocked object with ObjectMapper. The object doesn't matter in that case. The code which produces the exception looks like this:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValueAsString(mock(Object.class));
The resulting exception message is this:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.mockito.codegen.Object$MockitoMock$nY0RyieU["mockitoInterceptor"]->org.mockito.internal.creation.bytebuddy.MockMethodInterceptor["serializationSupport"])
The ObjectMapper comes from jackson-databind v2.14.0, for mockito I'm using version 4.8.1
TL; DR
Mock objects aren't data structures, you can't serialize them by ObjectMapper.
Full answer
You are trying to serialize a mock object which is very special kind of object created by Mockito. It is very different from a ordinary data structures that are processable by ObjectMapper.
What ObjectMapper does is that it looks at the members of a serialized object and tries to serialize each of them. It either knows, how to do that (int, Long...), or it is configured (often right after a new instance creation), or the serialized member has some annotations to tell the ObjectMapper. In your case the mock object has a member of type ByteBuddyCrossClassLoaderSerializationSupport and the ObjectMapper has no idea what to do.

Jackson fails to recognize #class type identifier in JSON payload

I have an hierarchy of Java POJOS, the base class being abstract. To ensure Jackson can deserialize from JSON into the correct concrete types I have annotated the base class with #JsonTypeInfo(use=JsonTypeInfo.Id.CLASS). However, I receive the following error when Jackson attemps deserialization:
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.foo.MyAbstractClass]: missing type id property '#class'
at [Source: (byte[])""{\"id\":10,\"params\":[\"foo\",\"bar\"],\"#class\":\"com.foo.MyConcreteClass\"}""; line: 1, column: 1]
The type identifier field #class is in the JSON payload but Jackson fails to find it. Any idea what's going on? Note that the Jackson deserialization is happening transparently; I am using Spring Cloud Stream.
Finally figured it out. Turns out the message payload was actually being interpreted by Jackson as a JSON String value and not a JSON object, due to how it was being sent by the producer application. By stripping the outer quotes and unescaping it Jackson was then parsing the string correctly.

UnrecognizedPropertyException in JSON with JERSEY

We get a org.codehaus.jackson.map.exc.UnrecognizedPropertyException with using Jerseys and Jackson as JSON-Mapper. We have an object with not native type as property (for example: not a String or int). When i use the annotation #JsonIgnore it's ok. But I must have the property.
Does anybody, which annotation should I use? In JAXB it's #XMLType?
We use Jersey 1.9.1 and Jackson 1.9.13.
I solved this. See my comment on the question.

Can not find a (Map) Key deserializer for type [simple type, class java.lang.Class<java.lang.Object>]

I used Jackson to serialize a Map<Class<?>, BaseClass>. There are multiple subclasses of BaseClass, and each one is properly annotated to be serialized/deserialized by Jackson.
Is it possible to invoke ObjectMapper.readValue(file, Subclass.class) and get a Subclass instance back?
If so, how do I avoid this exception?
com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class java.lang.Class<java.lang.Object>]
at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:578)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:168)
at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:404)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:231)
at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:581)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:369)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:842)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:514)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:292)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:241)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:381)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3154)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3047)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2100)
Shouldn't Jackson know how to deserialize Class<?> since it is a core JDK type?
UPDATE: I found https://stackoverflow.com/a/13954871/14731 which discusses how to implement Polymorphism in Jackson. That answers question #1 but leaves us with questions #2 and #3.
UPDATE2: Interesting. I found ClassSerializer.java but there is no corresponding ClassDeserializer.java in https://github.com/FasterXML/jackson-databind/tree/master/src/main/java/com/fasterxml/jackson/databind/deser/std
UPDATE3: Filed a bug report: https://github.com/FasterXML/jackson-databind/issues/630
This is a known bug that should be fixed in version 2.5.0: https://github.com/FasterXML/jackson-databind/issues/630

How to ignore new fields for an object model with Firebase 1.0.2

I'm using the last version at the moment of Firebase dependency, which is 1.0.2 and I'm having problems into getting my pojos parsed correctly.
The thing is, at any time the schema can changed but I don't want my app to crash with this:
D/AndroidRuntime(14097): Shutting down VM W/dalvikvm(14097):
threadid=1: thread exiting with uncaught exception (group=0x40a451f8)
E/AndroidRuntime(14097): FATAL EXCEPTION: main
E/AndroidRuntime(14097): com.firebase.client.FirebaseException: Failed
to bounce to type E/AndroidRuntime(14097): at
com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:213)
Looking into the dependency tree I get that Firebase is using Jackson mapper 1.9.7, so the annotation #JsonIgnoreProperties(ignoreUnknown = true") is not an option. Moreover, the object mapper is wrapped into this Firebase object so I can't configure the DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES property (DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES for Jackson 1.9 and before).
Is there any way to set this property, either as a class-level annotation or configuring the mapper or any other mechanism whatsoever?
The best solution would be that Firebase 1.0.3 started using Jackson 2.0, but don't know if this is something they care about right now.
Note: I've already thought about excluding the transitive Jackson 1.9.7 dependency and adding Jackson 2.0 so that I can access to this ignoreUnknown feature, but I don't think it is a viable choice since I would be changing the mayor version.
For those who have moved over to Google's official version of Firebase (As of May 29, 2016), you can use #Exclude instead of #JsonIgnore or #JsonProperty. Here is the link to their document.
Example:
public class dataPacket{
public String data;
...
#Exclude
public String getData(){return data;}
}
Update:
As others pointed, annotation #Exclude is right way to use it now. But if you use Kotlin that won't work. For Kotlin use
#Exclude #JvmField
var data: String? = nil
//or
#set:Exclude #get:Exclude
var data: String? = nil
Because annotation can be applied only for generated fields and not to properties.
Old answer:
I'm coming to Firebase from GSON were I used transient keyword. And that works with Firebase too
public transient String data;
As the accepted answer states, Firebase now uses Jackson, so you can annotate the desired methods you wish to ignore with
#JsonIgnore
Edit:
Firebase changed everything. Woot. Now use this instead:
#Exclude
Firebase 1.0.3 was released and now uses Jackson 2.2.2, so annotation #JsonIgnore is the way to go.
Edit:
as of now in 2017, Firebase doesn't use Jackson anymore. the correct annotation is #Exclude.

Categories