Skip to content

Failure to read AnnotatedField value in Jackson 2.11 #2789

@isaki

Description

@isaki

I am reporting this issue for tracking purposes; I fully intend to submit a PR once I narrow down the root cause and come up with an acceptable fix.

Version Information

  • Java: Corretto-11.0.7.10.1 (OpenJDK 11; macOS), OpenJDK 8u252 (Ubuntu 16 Server)
  • Jackson: 2.11.1

Thankfully, this is failing in my unit tests on both my build environments so that makes this easy to debug.

com.fasterxml.jackson.databind.JsonMappingException: Failed to getValue() for field io.isaki.jsandbox.JacksonDatabindTest$DataParent#type: class com.fasterxml.jackson.databind.introspect.AnnotatedField cannot access a member of class io.isaki.jsandbox.JacksonDatabindTest$DataParent with modifiers "private final"
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._wrapAsIOE(DefaultSerializerProvider.java:509)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:482)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4374)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3629)
	at io.isaki.jsandbox.JacksonDatabindTest.testAnnotatedField(JacksonDatabindTest.java:25)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.IllegalArgumentException: Failed to getValue() for field io.isaki.jsandbox.JacksonDatabindTest$DataParent#type: class com.fasterxml.jackson.databind.introspect.AnnotatedField cannot access a member of class io.isaki.jsandbox.JacksonDatabindTest$DataParent with modifiers "private final"
	at com.fasterxml.jackson.databind.introspect.AnnotatedField.getValue(AnnotatedField.java:113)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._typeIdDef(BeanSerializerBase.java:717)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeWithType(BeanSerializerBase.java:635)
	at com.fasterxml.jackson.databind.ser.impl.TypeWrappedSerializer.serialize(TypeWrappedSerializer.java:32)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	... 30 more
Caused by: java.lang.IllegalAccessException: class com.fasterxml.jackson.databind.introspect.AnnotatedField cannot access a member of class io.isaki.jsandbox.JacksonDatabindTest$DataParent with modifiers "private final"
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
	at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075)
	at java.base/java.lang.reflect.Field.get(Field.java:416)
	at com.fasterxml.jackson.databind.introspect.AnnotatedField.getValue(AnnotatedField.java:110)
	... 34 more
import static org.junit.Assert.assertEquals;

import java.util.Objects;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeId;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonDatabindTest {

    @Test
    public void testAnnotatedField() throws JsonProcessingException {
        final DataParent test = new DataClassA();

        final ObjectMapper mapper = new ObjectMapper();
        final String json = mapper.writeValueAsString(test);

        final DataParent copy = mapper.readValue(json, DataParent.class);
        assertEquals(DataType.CLASS_A, copy.getType());
    }

    private enum DataType {
        CLASS_A;
    }

    @JsonAutoDetect(
        getterVisibility = JsonAutoDetect.Visibility.NONE,
        creatorVisibility = JsonAutoDetect.Visibility.NONE,
        isGetterVisibility = JsonAutoDetect.Visibility.NONE,
        fieldVisibility = JsonAutoDetect.Visibility.NONE,
        setterVisibility = JsonAutoDetect.Visibility.NONE)
    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type",
        visible = true)
    @JsonSubTypes({
        @Type(name = "CLASS_A", value = DataClassA.class)
    })
    private static abstract class DataParent {

        @JsonProperty("type")
        @JsonTypeId
        private final DataType type;

        @SuppressWarnings("unused")
        DataParent() {
            super();
            this.type = null;
        }

        DataParent(final DataType type) {
            super();
            this.type = Objects.requireNonNull(type);
        }

        public final DataType getType() {
            return this.type;
        }
    }

    private static final class DataClassA extends DataParent {

        DataClassA() {
            super(DataType.CLASS_A);
        }
    }
}

EDIT: This test works fine with Jackson 2.9.10 (with 2.9.10.4).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions