question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Incompatible FAIL_ON_MISSING_PRIMITIVE_PROPERTIES and field level @JsonProperty

See original GitHub issue

Describe the bug The FAIL_ON_MISSING_PRIMITIVE_PROPERTIES is not working properly with field level @JsonProperty annotation. The @JsonProperty annotation is simply ignored.

Version information Currently latest 2.12, Java 15.0.1

To Reproduce If you have a way to reproduce this with:

  1. You can use the JUnit 5 test below to reproduce the issue:
class JsonPropertyAndFailOnNullForPrimitivesTest {

    @Test
    void test() throws JsonProcessingException {
        assertEquals(
                JsonMapper.builder()
                        .addModules(new ParameterNamesModule())
                        .constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED)
                        .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
                        .build()
                        .readValue("{\"aa\": 8}", TestClass.class)
                        .a,
                8);
    }

    private static class TestClass {

        @JsonProperty("aa")
        private final int a;

        TestClass(int a) {
            this.a = a;
        }
    }
}
  1. The test fails with the following error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot map `null` into type int (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)
 at [Source: (String)"{"aa": 8}"; line: 1, column: 9] (through reference chain: jackson.test.JsonPropertyAndFailOnNullForPrimitivesTest$TestClass["a"])

	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1577)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$PrimitiveOrWrapperDeserializer.getNullValue(NumberDeserializers.java:175)
	at com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer._findMissing(PropertyValueBuffer.java:204)
	at com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer.getParameters(PropertyValueBuffer.java:160)
	at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromObjectWith(ValueInstantiator.java:288)
	at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:202)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:520)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1390)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:362)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4591)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3546)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3514)
	at jackson.test.JsonPropertyAndFailOnNullForPrimitivesTest.test(JsonPropertyAndFailOnNullForPrimitivesTest.java:23)
  1. Note that other combinations work - not using a primitive type, moving the annotation on the constructor parameter or disabling the FAIL_ON_NULL_FOR_PRIMITIVES feature. The issue seems to be unrelated to the fact that I use a single argument constructor, I used single property for simlicity in the test. In other words, the new .constructorDetector(ConstructorDetector.USE_PROPERTIES_BASED) appears to be irrelevant for this bug.

Expected behavior The FAIL_ON_MISSING_PRIMITIVE_PROPERTIES feature should be aware of property names mapping through @JsonProperty when used on fields.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:5
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
GeorgiPetkovcommented, Dec 28, 2020

@cowtowncoder Seems like I’m doing a really great job as a rubber duck 🤞

1reaction
cowtowncodercommented, Dec 28, 2020

@GeorgiPetkov No the problem is that:

  1. JSON has property “aa”
  2. Constructor expects property “a”
  3. Due to essentially missing “a”, null must be passed as placeholder (constructor must get some value for the argument
  4. Nulls are not allowed for primitive values like int since you have FAIL_ON_NULL_PRIMITIVES

In addition there is field a renamed as aa into which incoming value is actually mapped (as to final, it’s just a detour for discussion but it is possible to prevent use of final fields as setters). So null comes from absence of value in this case.

Now: normally there should be association between field and constructor parameter, as their implicit names match: and after this linkage exist, they are part of a single logical property and that property would get renamed as aa. Further, constructor parameter having higher precedence would make it be used and field essentially ignored for deserialization.

This linkage, in turn, is missing because fields, methods, and name-annotated constructor parameters are introspected by POJOPropertiesCollector (originally all ctor parameters had to be annotated, before Java 5) – but ones which implicit names are only handled at a later point. The end result is that while both accessors are found, annotation “sharing” across accessors does not work – annotation merging occurs in POJOPropertiesCollector

This does give me an idea, however, regarding possibly (fingers crossed) finding linkage via implicit name, in addition to explicit name (explicit meaning “defined by annotation” and implicit “name derived from field/method name in bytecode”). While it would not enable annotation merging per se, it could cover this case where the only effect of annotation is renaming.

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - When is the @JsonProperty property used and what is it ...
Here's a good example. I use it to rename the variable because the JSON is coming from a .Net environment where properties start...
Read more >
Duplicate properties with upper-case field name and ... - GitHub
Duplicate properties with upper-case field name and JsonProperty annotation ... Not a bug but results from incompatible field/getter/setter naming -- fields ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found