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

@JsonIgnore no longer works for transient backing fields #3948

Closed
jlaber opened this issue May 22, 2023 · 5 comments
Closed

@JsonIgnore no longer works for transient backing fields #3948

jlaber opened this issue May 22, 2023 · 5 comments
Milestone

Comments

@jlaber
Copy link

jlaber commented May 22, 2023

Describe the bug
After upgrading jackson-databind, properties were being exposed after serialization that were set to @JsonIngore and shouldn't be.

Version information
Which Jackson version(s) was this for? 2.15.+ (seeing with both 2.15.0 and 2.15.1)
JDK - Temurin-17.0.6+10

To Reproduce
If you have a way to reproduce this with:
Example unit test showing the issue. If referencing 2.14.+ it works, but fails on these assertions when using 2.15.+:
assertFalse(json.contains("world"));
assertNotEquals(obj1.getDef(), obj2.getDef());
assertNull(obj2.getDef());

Code:

package org.example;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import java.io.Serial;
import java.io.Serializable;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

public class JacksonTest {

    public static class Obj implements Serializable {

        @Serial
        private static final long serialVersionUID = -1L;

        private String abc;

        @JsonIgnore
        private transient String def;

        public String getAbc() {
            return abc;
        }

        public void setAbc(String abc) {
            this.abc = abc;
        }

        public String getDef() {
            return def;
        }

        public void setDef(String def) {
            this.def = def;
        }
    }

    @Test
    public void testJsonIgnore() throws JsonProcessingException {
        var mapper = new ObjectMapper();

        var obj1 = new Obj();
        obj1.setAbc("hello");
        obj1.setDef("world");
        String json = mapper.writeValueAsString(obj1);
        var obj2 = mapper.readValue(json, Obj.class);

        assertEquals(obj1.getAbc(), obj2.getAbc());

        assertFalse(json.contains("world"));
        assertNotEquals(obj1.getDef(), obj2.getDef());
        assertNull(obj2.getDef());
    }
}

Expected behavior
The test should pass the same as it did with 2.14.+

Additional context
I noticed that using the 2.15.+ version, if I set mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true), it does start working.

Did the default somehow change? This is concerning because usages of the library could start exposing sensitive data that it wasn't in previous versions and this would be unknowingly. Since this is a minor (2.14 -> 2.15) this seems to be a big change that should be saved for a major.

I did verify mapper.isEnabled(MapperFeature.PROPAGATE_TRANSIENT_MARKER) is false in both 2.14 and 2.15, but it seems to be working in 2.14 without needing to set it to true.

@jlaber jlaber added the to-evaluate Issue that has been received but not yet evaluated label May 22, 2023
@cowtowncoder
Copy link
Member

cowtowncoder commented May 22, 2023

I think it was a big surprise to find that some users had used transient fields for annotations and this use case was never tested. As a consequence an unrelated change (fix to order of pruning accessors) changed behavior in this case -- but since it wasn't tested change was not uncovered.
So this was not an intentional behavioral change.

No change was made to PROPAGATE_TRANSIENT_MARKER default; but note that its semantics are not used in this case (change is not related to this setting although obviously there is some overlap in usage).

At this point it is not clear whether it is possible to change behavior to match pre-2.15.
I would recommend enabling MapperFeature.PROPAGATE_TRANSIENT_MARKER if that works around the problem.

EDIT: (18-Jul-2023)

Change probably due to fix for #3682:

957ee39

@cowtowncoder cowtowncoder removed the to-evaluate Issue that has been received but not yet evaluated label May 22, 2023
@cpu-meltdown
Copy link

@cowtowncoder Is it on the roadmap to fix this in 2.16? Or is enabling PROPAGATE_TRANSIENT_MARKER the only workaround?

@cowtowncoder
Copy link
Member

@cpu-meltdown I have no current plans to change behavior here, although it is possible that with more time (or someone else contributing change) this could be change to work the way it did pre-2.15.

Also note that another way that would have avoided the issue is to annotate getter or setter instead of field; that is, move the annotation.
(it is probably a personal preference but I always considered annotating getters or setters to be the default way, and not fields -- as non-public fields themselves are not visible for serialization without matching getter or annotation).

So: I would recommend using one of 2 work-arounds at this point since there are no immediate plans of tackling this issue.

cowtowncoder added a commit that referenced this issue Jul 19, 2023
@cowtowncoder cowtowncoder changed the title @JsonIgnore no longer works for transient backing fields when upgrading jackson-databind from 2.14.+ to 2.15.+ @JsonIgnore no longer works for transient backing fields Jul 19, 2023
@cowtowncoder cowtowncoder added this to the 2.16.0 milestone Jul 19, 2023
@cowtowncoder
Copy link
Member

Oh wow. Fix looks very simple, see PR #4048. Wish I could backport to 2.15, but I have a feeling there's non-trivial risk of regression so will merge in 2.16 for 2.16.0.

@JooHyukKim
Copy link
Member

nice one 👍🏻

axeloradmin pushed a commit to axelor/axelor-open-platform that referenced this issue Sep 14, 2023
It fixes jackson transient serialization bug introduce in 2.15 : FasterXML/jackson-databind#3948

Signed-off-by: Pierre Belloy <p.belloy@axelor.com>
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