From db5259292cb38977b08cab208dcebbab93a1469c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 6 May 2016 09:56:31 +0200 Subject: [PATCH] DATACMNS-853 - Support interface entity types using generated property accessors. Property accessors (getter and setter) defined on an interface require a different instruction opcode for invoking methods. We now distinguish whether a property accessor is defined on an interface and use either INVOKEINTERFACE or INVOKEVIRTUAL otherwise. Related tickets: DATACMNS-809. Original pull request: #161. Related pull request: #160. --- ...lassGeneratingPropertyAccessorFactory.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java index 10c590a04..cf5e321bf 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -876,8 +876,17 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert } else { // bean.get... mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(getter.getDeclaringClass()), getter.getName(), - String.format("()%s", signatureTypeName(getter.getReturnType())), false); + + int invokeOpCode = INVOKEVIRTUAL; + Class declaringClass = getter.getDeclaringClass(); + boolean interfaceDefinition = declaringClass.isInterface(); + + if(interfaceDefinition){ + invokeOpCode = INVOKEINTERFACE; + } + + mv.visitMethodInsn(invokeOpCode, Type.getInternalName(declaringClass), getter.getName(), + String.format("()%s", signatureTypeName(getter.getReturnType())), interfaceDefinition); autoboxIfNeeded(getter.getReturnType(), autoboxType(getter.getReturnType()), mv); } } else { @@ -1051,8 +1060,17 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert Class parameterType = setter.getParameterTypes()[0]; mv.visitTypeInsn(CHECKCAST, Type.getInternalName(autoboxType(parameterType))); autoboxIfNeeded(autoboxType(parameterType), parameterType, mv); - mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(setter.getDeclaringClass()), setter.getName(), - String.format("(%s)V", signatureTypeName(parameterType)), false); + + int invokeOpCode = INVOKEVIRTUAL; + Class declaringClass = setter.getDeclaringClass(); + boolean interfaceDefinition = declaringClass.isInterface(); + + if(interfaceDefinition){ + invokeOpCode = INVOKEINTERFACE; + } + + mv.visitMethodInsn(invokeOpCode, Type.getInternalName(setter.getDeclaringClass()), setter.getName(), + String.format("(%s)V", signatureTypeName(parameterType)), interfaceDefinition); } } else {