Skip to content
This repository has been archived by the owner on Nov 7, 2019. It is now read-only.

@JsonIgnore not preserved on static setter in an abstract class #25

Closed
Maxouwell opened this issue Aug 21, 2015 · 4 comments
Closed

@JsonIgnore not preserved on static setter in an abstract class #25

Maxouwell opened this issue Aug 21, 2015 · 4 comments
Milestone

Comments

@Maxouwell
Copy link

When deserialising, the MrBean module seems to not preserve the @JsonIgnore Annotation.

Test code following :

public class IgnoreBugTest {

    public static final ObjectMapper mapper = new ObjectMapper()
            .registerModule(new MrBeanModule())
            .enable(SerializationFeature.INDENT_OUTPUT);

    public AbstractRoot root;

    public IgnoreBugTest() throws JsonParseException, JsonMappingException, IOException {}

    public void setRoot(AbstractRoot root) {
        this.root = root;
    }

    public AbstractRoot getRoot() {
        return root;
    }

    public static void main(String[] args) throws Exception {
        IgnoreBugTest ibt = new IgnoreBugTest();

        Root root = new Root();
        root.setX(2);
        root.setY(3);

        ibt.setRoot(root);

        String jsonValue = mapper.writeValueAsString(ibt);
        System.out.println(jsonValue);
        System.out.println(mapper.readValue(jsonValue, IgnoreBugTest.class));
    }

}

public class Root extends AbstractRoot {

    private int y = 0;

    public Root() {}

    public void setY(int y) {
        this.y = y;
    }

    public int getY() {
        return y;
    }
}

@JsonTypeInfo(use=JsonTypeInfo.Id.MINIMAL_CLASS, include=JsonTypeInfo.As.PROPERTY)
public abstract class AbstractRoot {

    private static Leaf leaf;

    private int x = 0;

    public AbstractRoot() {}

    @JsonIgnore
    public static void setLeaf(Leaf leaf) {
        AbstractRoot.leaf = leaf;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

}

//@JsonIgnoreProperties(value={"leaf"} ,ignoreUnknown=true)
public abstract class AbstractRoot {

    private static Leaf leaf;

    private int x = 0;

    public AbstractRoot() {}

    @JsonIgnore
    public static void setLeaf(Leaf leaf) {
        AbstractRoot.leaf = leaf;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

}

//Bad jackson class, to generate the IllegalArgumentException
//This class should be ignored by Jackson
public class Leaf {

    public String test;


    public void setTest(String test) {
        this.test = test;
    }

    public void setTest(StringBuilder test) {
        this.test = test.toString();
    }
}

This code fail on deserialization, because it's try to check the Leaf class, which should be ignored.

Caused by: java.lang.IllegalArgumentException: Conflicting setter definitions for property "test": org.l6m.Leaf#setTest(1 params) vs org.l6m.Leaf#setTest(1 params)
    at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getSetter(POJOPropertyBuilder.java:293)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.filterBeanProps(BeanDeserializerFactory.java:583)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:479)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:220)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:409)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:358)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265)
    ... 19 more

Jackson does not take into account the Leaf class if :

  • The abstract class is annoted with @JsonIgnoreProperties, with the leaf property as value
  • If the class used for the root property in IgnoreBugTest is Root and not AbstractRoot
@cowtowncoder
Copy link
Member

Your test has a bug in that setLeaf is static method. Static methods are never considered to relate to properties, and as such annotations have no effect (setter is not used at all). But since there is leaf field, that is considered to be usable for deserialization.

But beyond this, would the test pass without mrbean module?

@Maxouwell
Copy link
Author

The code fail in the same way with the following code :

//@JsonIgnoreProperties(value={"leaf"} ,ignoreUnknown=true)
public abstract class AbstractRoot {

    @JsonIgnore
    private static Leaf leaf;

    private int x = 0;

    public AbstractRoot() {}

    @JsonIgnore
    public static void setLeaf(Leaf leaf) {
        AbstractRoot.leaf = leaf;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }
}

"leaf" is marked ignored in both the static method and the leaf field, but the MrBeanModule try to set it on deserialization.

If I remove the MrBeanModule, the test fail as Jackson can't instantiate the abstract class.

@cowtowncoder
Copy link
Member

Hmmh. I am still not sure I fully understand. As I pointed out, any annotation associated with a static field or method will be ignored by default, regardless of mrbean module: they are not related to class instances, only class. As such it does not matter what annotations you do or do not add.

But perhaps you are saying that mrbean module is accidentally looking at static methods, where it should not? If so, that would be a bug indeed.

@cowtowncoder cowtowncoder added this to the 2.2.3 milestone Sep 15, 2015
@cowtowncoder
Copy link
Member

Ok, yes indeed. So mrbean was accidentally considering static methods, mistaking that setLeaf as real setter. Fixed this for 2.5(.5) and 2.6(.3). Unfortunately this did not quite make it in 2.6.2, as it was just released earlier today.

Thank you for reporting this.

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

No branches or pull requests

2 participants