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 read Optionals written with StdTypeResolverBuilder #86

Open
isopov opened this issue Oct 12, 2018 · 6 comments
Open

Cannot read Optionals written with StdTypeResolverBuilder #86

isopov opened this issue Oct 12, 2018 · 6 comments
Labels
2.19 pr-welcome Issue for which progress most likely if someone submits a Pull Request

Comments

@isopov
Copy link

isopov commented Oct 12, 2018

The following test fails on Jackson 2.9.7 and passes on 2.8.11:

    @Test
    public void test() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDefaultTyping(
                new StdTypeResolverBuilder()
                        .init(JsonTypeInfo.Id.CLASS, null)
                        .inclusion(JsonTypeInfo.As.WRAPPER_OBJECT)
        );
        mapper.registerModule(new Jdk8Module());
        String json = mapper.writeValueAsString(new Foo(Optional.of(1)));
        System.out.println(json);
        mapper.readValue(json, Foo.class);
    }

    public static class Foo {
        private Optional<Integer> bar;

        public Foo() {
        }

        public Foo(Optional<Integer> bar) {
            this.bar = bar;
        }

        public Optional<Integer> getBar() {
            return bar;
        }

        public void setBar(Optional<Integer> bar) {
            this.bar = bar;
        }
    }

Complete runnable project with this test-case can be found on https://github.com/isopov/jackson-optional-test

@isopov isopov changed the title Cannot read read written Optionals with StdTypeResolverBuilder Cannot read Optionals written with StdTypeResolverBuilder Oct 12, 2018
@isopov
Copy link
Author

isopov commented Oct 24, 2018

Added workaround, involving copy&pasting classes from 2.8.11 - https://github.com/isopov/jackson-optional-test/blob/workaround/src/test/java/com/example/OptionalJacksonTest.java

Still proper fix will be highly appreciated.

@cowtowncoder cowtowncoder added 2.9 active Issue being actively investigated and/or worked on labels Oct 30, 2018
@cowtowncoder
Copy link
Member

cowtowncoder commented Oct 30, 2018

I will have to say that it is quite possible that combination of polymorphic type in Optional for root value may be unsupportable. I would strongly recommend not using that combination: partly since root values have significant challenges wrt type erasure, and partly as Optionals are challenging in their own right.

In fact I am considering adding a warning that polymorphic type handling is not recommended to be used for root values at all.

Having said that: I will try to figure out if this can be made to work correctly (although depending on changes they might only be made to 2.9 branch), and I hope this is the case.

Thank you for reporting the problem.

EDIT Looking at this further, Optional is NOT used as root value. So that's not the problem.

@cowtowncoder cowtowncoder added 2.10 and removed 2.9 labels Aug 13, 2019
@cowtowncoder
Copy link
Member

To help future work, output looks like:

{"com.fasterxml.jackson.datatype.jdk8.PolymorphicOptionalTest$Foo":{"bar":1}}

and that would seem to be missing type information for contents, somehow.

@cowtowncoder cowtowncoder added 2.11 and removed 2.10 active Issue being actively investigated and/or worked on labels Oct 9, 2019
@cowtowncoder cowtowncoder removed the 2.11 label Apr 21, 2022
@cowtowncoder cowtowncoder added pr-welcome Issue for which progress most likely if someone submits a Pull Request 2.19 labels Dec 7, 2024
@cowtowncoder
Copy link
Member

@JooHyukKim this might be worth looking into as well.

@JooHyukKim
Copy link
Member

Ah so this is how we want the output object is in 2.8.

{
    "com.fasterxml.jackson.datatype.jdk8.OptionalStdTypeResolverBuilder86Test$Foo": {
        "bar": {
            "java.util.Optional": 1
        }
    }
}

If we try to read above JSON output from 2.8, in later version, throws error saying...

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'java.util.Optional' as a subtype of `java.lang.Integer`: Not a subtype
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 4, column: 13] (through reference chain: com.fasterxml.jackson.datatype.jdk8.OptionalStdTypeResolverBuilder86Test$Foo["bar"])

	at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
	at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:2041)
	at com.fasterxml.jackson.databind.DatabindContext._throwNotASubtype(DatabindContext.java:291)
	at com.fasterxml.jackson.databind.DatabindContext.resolveAndValidateSubType(DatabindContext.java:252)
	at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver._typeFromId(ClassNameIdResolver.java:76)

@cowtowncoder
Copy link
Member

Hmmmh. Now that I think about this, there's a problem... Although we do need the type id of the contained value, we also need to know there's Optional in-between.
So not 100% sure what type id is needed. It's almost as if we needed Optional<Integer>.
To further complicate things tho, Integer is so-called "natural" type, for which no type id is to be output. Ugh.

I also realized that the test case is incomplete; it doesn't seem to verify actual contents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.19 pr-welcome Issue for which progress most likely if someone submits a Pull Request
Projects
None yet
3 participants