From d85d74cdf55bc8b53eb028c70afcd99074b080a0 Mon Sep 17 00:00:00 2001 From: Harrison Houghton Date: Wed, 18 Jul 2018 10:19:05 -0400 Subject: [PATCH] Interfaces may have non-abstract methods (since java8) and those methods may override abstract methods in superinterfaces, so don't skip the `hasConcreteOverride` method just because we're materializing an interface. --- .../jackson/module/mrbean/BeanBuilder.java | 19 ++++++------ .../module/mrbean/TestDefaultMethods.java | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 mrbean/src/test/java/com/fasterxml/jackson/module/mrbean/TestDefaultMethods.java diff --git a/mrbean/src/main/java/com/fasterxml/jackson/module/mrbean/BeanBuilder.java b/mrbean/src/main/java/com/fasterxml/jackson/module/mrbean/BeanBuilder.java index 71dbf276..8ea5079b 100644 --- a/mrbean/src/main/java/com/fasterxml/jackson/module/mrbean/BeanBuilder.java +++ b/mrbean/src/main/java/com/fasterxml/jackson/module/mrbean/BeanBuilder.java @@ -70,8 +70,7 @@ public BeanBuilder implement(boolean failOnUnrecognized) // First: find all supertypes: implTypes.add(_type); BeanUtil.findSuperTypes(_type, Object.class, implTypes); - final boolean hasConcrete = !_type.isInterface(); - + for (JavaType impl : implTypes) { TypeResolutionContext ctxt = buildTypeContext(impl); @@ -109,7 +108,7 @@ public BeanBuilder implement(boolean failOnUnrecognized) continue; } // [module-mrbean#11]: try to support overloaded methods - if (hasConcrete && hasConcreteOverride(m, _type)) { + if (hasConcreteOverride(m, _type)) { continue; } if (failOnUnrecognized) { @@ -126,7 +125,7 @@ public BeanBuilder implement(boolean failOnUnrecognized) /** * Method that generates byte code for class that implements abstract * types requested so far. - * + * * @param className Fully-qualified name of the class to generate * @return Byte code Class instance built by this builder */ @@ -171,7 +170,7 @@ public byte[] build(String className) /** * Helper method used to detect if an abstract method found in a base class * may actually be implemented in a (more) concrete sub-class. - * + * * @since 2.4 */ protected boolean hasConcreteOverride(Method m0, JavaType implementedType) @@ -191,7 +190,7 @@ protected boolean hasConcreteOverride(Method m0, JavaType implementedType) } return false; } - + protected String getPropertyName(String methodName) { int prefixLen = methodName.startsWith("is") ? 2 : 3; @@ -215,7 +214,7 @@ protected void addGetter(TypeResolutionContext ctxt, Method m) POJOProperty prop = findProperty(ctxt, getPropertyName(m.getName())); // only set if not yet set; we start with super class: if (prop.getGetter() == null) { - prop.setGetter(m); + prop.setGetter(m); } } @@ -236,13 +235,13 @@ protected POJOProperty findProperty(TypeResolutionContext ctxt, String propName) } return prop; } - + protected final static boolean returnsBoolean(Method m) { Class rt = m.getReturnType(); return (rt == Boolean.class || rt == Boolean.TYPE); } - + /* /********************************************************** /* Internal methods, bytecode generation @@ -290,7 +289,7 @@ private DynamicType.Builder createSetter(DynamicType.Builder builder, /* Internal methods, other /********************************************************** */ - + protected String decap(String name) { char c = name.charAt(0); if (name.length() > 1 diff --git a/mrbean/src/test/java/com/fasterxml/jackson/module/mrbean/TestDefaultMethods.java b/mrbean/src/test/java/com/fasterxml/jackson/module/mrbean/TestDefaultMethods.java new file mode 100644 index 00000000..108704a0 --- /dev/null +++ b/mrbean/src/test/java/com/fasterxml/jackson/module/mrbean/TestDefaultMethods.java @@ -0,0 +1,31 @@ +package com.fasterxml.jackson.module.mrbean; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class TestDefaultMethods + extends BaseTest { + + public interface HasId { + long id(); + } + + public interface HasLeguminousId extends HasId { + long getId(); + default long id() { return getId(); } + } + + public void testMaterializedDefaultMethod() throws IOException { + final ObjectMapper mapper = newMrBeanMapper(); + + final String input = "{\"id\": 0}"; + + final HasLeguminousId bean = mapper.readValue(input, HasLeguminousId.class); + + assertEquals(bean.getId(), 0L); + assertEquals(bean.id(), 0L); // shouldn't be implemented by mrbean + + } + +}