Skip to content

IncompatibleClassChangeError deserializing interface methods with default impl #30

@shawnsmith

Description

@shawnsmith

With Afterburner I'm getting the exception java.lang.IncompatibleClassChangeError: Found class <MyClass>, but interface was expected trying to deserialize an object where a setter is implemented in an interface.

I've tested with Jackson+Afterburner 2.8.7, 2.8.10 and 2.9.0 and all fail in the same way. (jdk 8)

java.lang.IncompatibleClassChangeError: Found class com.fasterxml.jackson.module.afterburner.deser.TestInterfaceDeser$Model, but interface was expected

	at com.fasterxml.jackson.module.afterburner.deser.TestInterfaceDeser$Model$Access4JacksonDeserializer5b28f286.stringSetter(com/fasterxml/jackson/module/afterburner/deser/TestInterfaceDeser$Model$Access4JacksonDeserializer.java)
	at com.fasterxml.jackson.module.afterburner.deser.SettableStringMethodProperty.deserializeAndSet(SettableStringMethodProperty.java:53)
	at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
	at com.fasterxml.jackson.module.afterburner.deser.testInterfaceDeserialize(TestInterfaceDeser.java:40)

Here's a test case that reproduces the issue:

package com.fasterxml.jackson.module.afterburner.deser;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class TestInterfaceDeser {

    public interface Typed {
        String getType();
        default void setType(String type) {
            if (!getType().equals(type)) {
                throw new IllegalStateException(String.format("Expected '%s': %s", getType(), type));
            }
        }
    }

    public static class Model implements Typed {
        @Override
        public String getType() {
            return "Model";
        }
    }

    @Test
    public void testInterfaceDeserialize() throws Exception {
        Model model = new Model();

        ObjectMapper mapper = new ObjectMapper().registerModule(new AfterburnerModule());

        String json = mapper.writeValueAsString(model);
        assertEquals("{\"type\":\"Model\"}", json);

        // Throws: java.lang.IncompatibleClassChangeError: Found class com.fasterxml.jackson.module.afterburner.deser. TestInterfaceDeser$Model, but interface was expected
        Model roundTrip = mapper.readValue(json, Model.class);

        assertNotNull(roundTrip);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions