FasterXML / jackson-modules-java8

Set of support modules for Java 8 datatypes (Optionals, date/time) and features (parameter names)
Apache License 2.0
401 stars 117 forks source link

Regression: private constructor no longer usable as creator #74

Closed scranen closed 6 years ago

scranen commented 6 years ago

The following test passes in 2.9.1, but fails in 2.9.2:

package com.fasterxml.jackson.module.paramnames;

import static org.assertj.core.api.BDDAssertions.then;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.junit.Test;

public class JsonCreatorWithPropertyNamingStrategyTest {

    @Test
    public void testPrivateConstructorWithAnnotations() throws Exception {
        verifyObjectDeserializationWithNamingStrategy(
                PropertyNamingStrategy.SNAKE_CASE,
                "{\"a\":1, \"b\": 2}",
                new ClassWithTwoProperties(1, 2));
    }

    private void verifyObjectDeserializationWithNamingStrategy(
            final PropertyNamingStrategy propertyNamingStrategy, final String json, Object expected)
            throws Exception {
        // given
        ObjectMapper objectMapper =
                new ObjectMapper()
                        .registerModule(new ParameterNamesModule())
                        .setPropertyNamingStrategy(propertyNamingStrategy)
                        .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
                        .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

        // when
        Object actual = objectMapper.readValue(json, expected.getClass());

        then(actual).isEqualToComparingFieldByField(expected);
    }

    static class ClassWithTwoProperties {
        public final int a;
        public final int b;

        private ClassWithTwoProperties(@JsonProperty("a") int a, @JsonProperty("b") int b) {
            this.a = a;
            this.b = b;
        }
    }
}

This may or may not be related to the changes that cause this regression.

cowtowncoder commented 6 years ago

I don't know why this used to pass, but I think it should not since you are explicitly disabling auto-detection of creators but are not using @JsonCreator marker. That is, it seems that earlier visibility checking was done incorrectly.

To resolve this, you would need to change visibility for creators by adding:

                    .setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY)

(or whatever baseline visibility you think is acceptable)