-
-
Notifications
You must be signed in to change notification settings - Fork 151
Description
I am not able to serialize objects that contain an interface for sub-classes using @JsonTypeInfo(use = Id.DEDUCTION)
. It works fine for JSON and reading YAML, but when I try to serialize the objects into a Yaml file I get an exception:
com.fasterxml.jackson.databind.JsonMappingException: Can not write a field name, expecting a value (through reference chain: jackson.MainDoc["profiles"]-]java.util.ArrayList[0]-]jackson.Profile["settings"]-]jackson.Setting1["application"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:402)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:361)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeWithType(BeanSerializerBase.java:657)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:735)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
I created a sample repo that shows the problem here: https://github.com/phaumer/jackson-yaml-deduction
I am working on a configuration file for our product that manages an array of profiles and depending of the type of the profile it would use a different settings object with different properties and sub-objects. The basic structure looks like this
name: doc1
profiles:
- name: profile1
type: type1
settings:
application: sam
command: test
- name: profile2
type: type2
settings:
mappings: map1
The settings object is declared as
@JsonTypeInfo(use = Id.DEDUCTION)
@JsonSubTypes({ @Type(value = Setting1.class, name = "settings"),
@Type(value = Setting2.class, name = "settings") })
public interface Setting { }
with two implementation classes for the two types of settings.
In the sample repo you see three test cases. The first one reads a sample file as json and writes it back without issues. The second one reads the yaml from above without problems, but throws the exception above when serializing it back with mapper.writeValue()
.
@Test
void testReadWriteYAML() throws Exception {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
File inputFile = Paths.get(inputYamlFilepath).toFile();
MainDoc doc = mapper.readValue(inputFile, MainDoc.class);
assertNotNull(doc);
assertEquals(createTestObject(), doc);
File outFile = Paths.get(outputYamlFilepath).toFile();
mapper.writeValue(outFile, doc);
}
The third example constructions the content as Java objects and can be serialized as json, but not yaml again.