-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IncompatibleClassChangeError
deserializing interface methods with default impl
#30
Comments
Try not using default methods? I can not unfortunately use this reproduction as Jackson 2.x does not require Java 8 and must build on Java 7. |
I've worked around it for now by specifying a custom serializer which makes Afterburner skip the property: @JsonDeserialize(using = PlainStringDeserializer.class)
default void setType(String type) {
...
} and public static class PlainStringDeserializer extends StdDeserializer<String> {
public PlainStringDeserializer() {
super(String.class);
}
@Override
public String deserialize(JsonParser jp, DeserializationContext ctx) throws IOException {
if (jp.getCurrentToken() != JsonToken.VALUE_STRING) {
return (String) ctx.handleUnexpectedToken(String.class, jp);
}
return jp.getText();
}
} Specifying the regular |
I think this needs to be tackled via Jackson 3.x version of project, to verify handling of default implementations. But fix itself can I hope be backported in 2.9.x. |
It looks like a fix along the following lines might work without requiring an In boolean isInterface = method.getDeclaringClass().isInterface();
mv.visitMethodInsn(isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, ...); with boolean isInterface = isInterfaceMethod(method);
mv.visitMethodInsn(isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, ...); and add public class DynamicPropertyAccessorBase
{
...
protected static boolean isInterfaceMethod(Method method) {
// Forward compatible with Java 8 equivalent: method.getDeclaringClass().isInterface() && !method.isDefault()
return method.getDeclaringClass().isInterface() &&
(method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) != Modifier.PUBLIC;
}
}
The implementation for |
Interesting. That could work... Thank you for doing this research; I have been swamped with other things and have limited time to use here, so having a solution speeds fixing up a lot. But so basically fundamental problem is that although method is defined in an interface, it is "materialized" as regular class method. And certainly seems to be missing |
IncompatibleClassChangeError
deserializing interface methods with default impl
Will be fixed in 2.8.11 (if ever released); 2.9.2. Oddly enough only seems to affect deserialization; serialization seemed ok. |
Awesome, thanks! |
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)
Here's a test case that reproduces the issue:
The text was updated successfully, but these errors were encountered: