Skip to content

Afterburner excludes serialization of some null-valued Object properties #7

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

Closed
toadzky opened this issue Mar 30, 2016 · 13 comments
Closed

Comments

@toadzky
Copy link

toadzky commented Mar 30, 2016

Originally I opened a ticket with Dropwizard (dropwizard/dropwizard#1482) and they tracked it down to the Afterburner module.

Apparently, when @Value annotated classes are serialized with the Afterburner module installed, it ignores inclusion settings and strips out null values.

@cowtowncoder
Copy link
Member

I would need a unit test to be able to reproduce and fix this: does not have to be complex, but ideally should be reproducible without additional third-party extensions.

@esiqveland
Copy link

esiqveland commented May 25, 2016

I am seeing this without using Lombok.
Small test example:

    @JsonInclude(JsonInclude.Include.ALWAYS)
    static class TestClass {
        @JsonProperty("name")
        private String name;
        @JsonProperty("id")
        private String id;
        @JsonProperty("created_at")
        private DateTime created_at;
        @JsonProperty("updated_at")
        private DateTime updated_at;

        public String getName() {
            return name;
        }

        public TestClass setName(String name) {
            this.name = name;
            return this;
        }

        public String getId() {
            return id;
        }

        public TestClass setId(String id) {
            this.id = id;
            return this;
        }

        public DateTime getCreated_at() {
            return created_at;
        }

        public DateTime getUpdated_at() {
            return updated_at;
        }

        public TestClass setCreated_at(final DateTime created_at) {
            this.created_at = created_at;
            return this;
        }

        public TestClass setUpdated_at(final DateTime updated_at) {
            this.updated_at = updated_at;
            return this;
        }

    }

    @Test
    public void test_serialize_jackson() throws JsonProcessingException {

        TestClass tilstand = new TestClass()
                .setId(null)
                .setName("name")
                .setUpdated_at(null)
                .setCreated_at(new DateTime());

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JodaModule());
        mapper.registerModule(new AfterburnerModule());

        String json = mapper.writeValueAsString(tilstand);

        assertThat(json, containsString("id"));
        assertThat(json, containsString("name"));
        assertThat(json, containsString("updated_at"));
        assertThat(json, containsString("created_at"));
    }

If you comment out AfterburnerModule, the test passes. I am using v. 2.6.3

@carterventures
Copy link

Seeing the exact same behavior as @esiqveland in 2.7.4. We are using Joda time. Null core java types, and custom objects we create are included in the serialized output, but the Joda time times are not included if they are null. Disabling Afterburner fixes the issue.

@cowtowncoder
Copy link
Member

cowtowncoder commented Jun 22, 2016

@carterventures I am not sure if it is the same issue, as description sounds bit different. It is probably related, just not sure if it's the same problem.

It would be good to file a separate issue, with enough code/declarations to reproduce your issue; I can then figure out if the root cause is the same. It is more difficult to follow up descriptions with multiple threads for things that may or may not be related.

@esiqveland
Copy link

Ok, I will file another issue for this tomorrow.

@cowtowncoder
Copy link
Member

@esiqveland thanks! I'll try to work on this today, will update if and when I find something.

@cowtowncoder
Copy link
Member

Hmmh. Ok, part of the problem is, I think, that fix to number types (to NOT consider default values as "empty" values) that went in 2.7.0 was not made for Joda date/times (or, for java.util.Date / java.util.Calendar for that matter). I wish this found earlier; I'll have to think of whether to try changing that for 2.7.6 or not.

But that alone would not explain problem wrt Afterburner. I am guessing Afterburner somehow gets into thinking inclusion mechanism NON_EMPTY would be used for "Object" values, that is, for values other than String, boolean, int or long.

One good thing is that I think I can repro this with just java.util.Date, which simplifies task a it, as I hope to avoid adding cross-dependency from here to there (otherwise Joda module must be released before these modules etc).

@cowtowncoder
Copy link
Member

Unfortunately I can not reproduce this with version 2.7.5, using same version for all components (jackson-databind, jackson-module-afterburner, jackson-datatype-joda); either using Joda DateTime or java.util.Date.

Is it possible that an older version of Afterburner might be used?

@carterventures
Copy link

I'm attaching an example Maven project that demonstrates the issue through a unit test. The "withAfterburner" test fails for me, the "withoutAfterburner" passes. I'm using Java "1.8.0_60".

jackson_archive_7.zip

@cowtowncoder
Copy link
Member

Thank you! I can reproduce the issue locally against 2.7 branch.

Interestingly enough, behavior of Joda DateTime does differ from java.util.Date somehow, so my earlier theory on this being related to NON_EMPTY handling appears wrong.

@cowtowncoder
Copy link
Member

Now this is interesting... looks like serializer is "broken", that is, during serialization an exception is thrown, which results in original serializer getting called. Why that decides to skip serialization is not clear yet, but at least I know where to look now.

@cowtowncoder cowtowncoder changed the title Afterburner doesn't play nicely with Lombok Afterburner excludes serialization of some null-valued Object properties Jun 24, 2016
@cowtowncoder
Copy link
Member

Ok, got it. Looks like overrides is needed for assignNullSerializer(), to delegate; broken is only marked to indicate "non-standard" serializer (that is, not default one Jackson itself assigns). So it only affects 3rd party types like Joda. Further, due to missing delegation for assigning null serializer, and 2.7 behavior of requiring null serializer (if missing, means "exclude if null"), problem occurs.

I'll write a non-Joda-dependant test and fix this.

@cowtowncoder
Copy link
Member

Very frustrating: while I know the reason for failure and can reproduce with Joda DateTime, I have failed to make custom types fail for some reason. Very peculiar. Will try to reproduce (to have regression test), but if worst comes to worst will just add the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants