Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot serialize YAML with Deduction-Based Polymorphism #404

Closed
phaumer opened this issue Mar 13, 2023 · 3 comments
Closed

Cannot serialize YAML with Deduction-Based Polymorphism #404

phaumer opened this issue Mar 13, 2023 · 3 comments
Labels
2.15 Fix or feature targeted at 2.15 release has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue yaml Issue related to YAML format backend
Milestone

Comments

@phaumer
Copy link

phaumer commented Mar 13, 2023

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.

@cowtowncoder cowtowncoder added the yaml Issue related to YAML format backend label Mar 13, 2023
@cowtowncoder
Copy link
Member

Ok, does not look like DEDUCTION use is tested against YAML backend. It should work but apparently does not.

What would help would be minimal reproduction (I know there's a full project) to reproduce failure to write a single value (or perhaps "write-then-read") with YAML backend. Ideally PR against 2.15 branch.
The issue likely has to do with YAML module's Type Id handling -- YAML has "native" type ids and handling is bit more involved; although with DEDUCTION no writes should occur using any type id functionality.

@cowtowncoder cowtowncoder added has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue 2.15 Fix or feature targeted at 2.15 release labels Apr 22, 2023
@cowtowncoder cowtowncoder added this to the 2.15.1 milestone May 4, 2023
@phaumer
Copy link
Author

phaumer commented May 18, 2023

I just saw that 2.15.1 was released and the tests in my sample repo are now passing. Thanks so much @cowtowncoder.

@cowtowncoder
Copy link
Member

Thank you for verifying @phaumer !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.15 Fix or feature targeted at 2.15 release has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue yaml Issue related to YAML format backend
Projects
None yet
Development

No branches or pull requests

2 participants