This is an automated email from the ASF dual-hosted git repository. davidb pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push: new 1431a1b [converter] handle default methods new 0cb4bb0 Merge pull request #10 from stbischof/conv_def_method 1431a1b is described below commit 1431a1bb2262cb60e6c072b49930f2f54e216e02 Author: Stefan Bischof <stbisc...@bipolis.org> AuthorDate: Wed Mar 18 19:14:39 2020 +0100 [converter] handle default methods --- .../org/osgi/util/converter/ConvertingImpl.java | 29 ++++++++++++++++++++++ .../org/osgi/util/converter/ConverterTest.java | 8 ++++++ .../util/converter/InterfaceWithDefaultMethod.java | 11 ++++++++ 3 files changed, 48 insertions(+) diff --git a/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java b/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java index c9e3722..0733060 100644 --- a/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java +++ b/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java @@ -17,6 +17,9 @@ package org.osgi.util.converter; import java.lang.annotation.Annotation; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -810,6 +813,32 @@ class ConvertingImpl extends AbstractSpecifying<Converting> if (cls.isAnnotation()) { val = method.getDefaultValue(); } + else if (method.isDefault()) + { + double javaVersion = Double.parseDouble( + System.getProperty("java.class.version")); + double java8 = 52.0; + if (javaVersion > java8) + { + val = MethodHandles.lookup().findSpecial( + method.getDeclaringClass(), method.getName(), + MethodType.methodType(method.getReturnType(), + new Class[] {}), + method.getDeclaringClass()).bindTo( + proxy).invokeWithArguments(args); + } + else + { + Constructor<Lookup> c = Lookup.class.getDeclaredConstructor( + Class.class); + if (!c.isAccessible()) + { + c.setAccessible(true); + } + val = c.newInstance(cls).in(cls).unreflectSpecial(method, + cls).bindTo(proxy).invokeWithArguments(args); + } + } if (val == null) { if (args != null && args.length == 1) { diff --git a/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java b/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java index ef00c13..166b9c9 100644 --- a/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java +++ b/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java @@ -1465,6 +1465,14 @@ public class ConverterTest { assertNotNull(k); } + @Test + public void testDefaultInterfaceMethod() throws Throwable + { + Class<?> clazz = InterfaceWithDefaultMethod.class; + InterfaceWithDefaultMethod i = (InterfaceWithDefaultMethod) Converters.standardConverter().convert( + new HashMap<String, Object>()).to(clazz); + assertEquals(InterfaceWithDefaultMethod.RESULT, i.defaultMethod()); + } static interface MyIntf2 { String code(); Integer value(); diff --git a/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java b/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java new file mode 100644 index 0000000..c8a42ff --- /dev/null +++ b/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java @@ -0,0 +1,11 @@ +package org.osgi.util.converter; + +public interface InterfaceWithDefaultMethod +{ + public static final String RESULT = "r"; + + public default String defaultMethod() + { + return RESULT; + } +} \ No newline at end of file