JsonTypeIdConflict3681Test.java
package com.fasterxml.jackson.databind.tofix;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
import static org.junit.jupiter.api.Assertions.assertNotNull;
// [databind#3681]: JsonSubTypes declared on multiple interfaces of a class
// results in order-dependent resolution and outcome
class JsonTypeIdConflict3681Test extends DatabindTestUtil {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(name = "a_impl", value = A_Impl.class)
})
private interface A {
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(name = "b_impl", value = B_Impl.class),
})
private interface B {
}
/**
* NOTE: the <b>"order"</b> of declarations on inherited interfaces makes
* the difference in how types are resolved here.
*/
private interface C extends B, A {
}
private static class A_Impl implements C {
}
private static class B_Impl implements B {
}
private static class WrapperC {
@JsonProperty
public C c;
}
private final ObjectMapper MAPPER = newJsonMapper();
/**
* Type resolution fails due to a conflict between the types --check the exception message below this test case.
* <p>
* This will only pass when we modify {@code C} to extend {@code A} first, like so:
* <pre>
* private interface C extends A, B {}
* </pre>
*/
@JacksonTestFailureExpected
@Test
void failureWithTypeIdConflict() throws Exception {
WrapperC c = MAPPER.readValue(a2q("{'c': {'type': 'c_impl'}}"), WrapperC.class);
assertNotNull(c);
}
}