Version of libraries:
* google-api-services-logging: v2-rev20210709-1.32.1
* jackson-core/databind/annotations: 2.11.2
* Not using Spring or Lombok
I'm attempting to deserialize com.google.api.services.logging.v2.model.LogEntry using ObjectMapper however I'm seeing this exception. It's trying to map the subclasses in LogEntry to a Map and fails. Note this is just an example of it trying to map the operation section of the JSON. If it attempts it for the other subclasses (depending on the JSON logs) its the same exception albeit with the different fields.
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not set com.google.api.services.logging.v2.model.LogEntryOperation field com.google.api.services.logging.v2.model.LogEntry.operation to java.util.LinkedHashMap (through reference chain: com.google.api.services.logging.v2.model.LogEntry["operation"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:356) at com.fasterxml.jackson.databind.deser.std.ContainerDeserializerBase.wrapAndThrow(ContainerDeserializerBase.java:181) at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:552) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:377) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4524) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3503) at com.abc.logging.data.parsing.LogEntryParser.parse(LogEntryParser.java:81) ... 28 more Caused by: java.lang.IllegalArgumentException: Can not set com.google.api.services.logging.v2.model.LogEntryOperation field com.google.api.services.logging.v2.model.LogEntry.operation to java.util.LinkedHashMap at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) at java.base/java.lang.reflect.Field.set(Field.java:780) at com.google.api.client.util.FieldInfo.setFieldValue(FieldInfo.java:275) at com.google.api.client.util.FieldInfo.setValue(FieldInfo.java:231) at com.google.api.client.util.GenericData.put(GenericData.java:98) at com.google.api.client.util.GenericData.put(GenericData.java:43) at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:547) ... 33 more
Given LogEntry is part of the Google logging v2 library I don't have access to add annotations but assumed it was fine given it extends GenericJson. The deserialization is pretty straight forward with:
byte[] data = jsonString.getBytes();
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(new ByteArrayInputStream(data), LogEntry.class);
I understand Jackson will default to a LinkedHashMap when it doesn't know what to deserialize to. Given this I attempted to use a mixin class like so to map these specific subclasses:
public abstract class LogEntryMixin {
@JsonDeserialize(using = LogEntryHttpRequestDeserializer.class)
private HttpRequest httpRequest;
@JsonDeserialize(using = LogEntryResourceMetadataDeserializer.class)
private MonitoredResourceMetadata metadata;
@JsonDeserialize(using = LogEntryResourceDeserializer.class)
private MonitoredResource resource;
@JsonDeserialize(using = LogEntryOperationDeserializer.class)
private LogEntryOperation operation;
@JsonDeserialize(using = LogEntrySourceLocationDeserializer.class)
private LogEntrySourceLocation sourceLocation;
}
And then I add it to the mapper like so:
byte[] data = jsonString.getBytes();
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(LogEntry.class, LogEntryMixin.class);
mapper.readValue(new ByteArrayInputStream(data), LogEntry.class);
However it doesn't seem to honor the mixin JsonDeserialize annotations I've added.
Has anyone else come across a similar issue? Any help would be appreciated. Thanks.