Skip to content

Commit 2d632ef

Browse files
committed
Fix SpEL generated code for default method invocation
Closes gh-25706
1 parent eec4a6d commit 2d632ef

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -244,7 +244,7 @@ private void updateExitTypeDescriptor() {
244244
Method method = ((ReflectiveMethodExecutor) executorToCheck.get()).getMethod();
245245
String descriptor = CodeFlow.toDescriptor(method.getReturnType());
246246
if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) {
247-
originalPrimitiveExitTypeDescriptor = descriptor;
247+
this.originalPrimitiveExitTypeDescriptor = descriptor;
248248
this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor);
249249
}
250250
else {
@@ -296,7 +296,7 @@ public boolean isCompilable() {
296296

297297
return true;
298298
}
299-
299+
300300
@Override
301301
public void generateCode(MethodVisitor mv, CodeFlow cf) {
302302
CachedMethodExecutor executorToCheck = this.cachedExecutor;
@@ -327,7 +327,7 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
327327
// Something on the stack when nothing is needed
328328
mv.visitInsn(POP);
329329
}
330-
330+
331331
if (CodeFlow.isPrimitive(descriptor)) {
332332
CodeFlow.insertBoxIfNecessary(mv, descriptor.charAt(0));
333333
}
@@ -340,8 +340,10 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
340340
}
341341

342342
generateCodeForArguments(mv, cf, method, this.children);
343-
mv.visitMethodInsn((isStaticMethod ? INVOKESTATIC : INVOKEVIRTUAL), classDesc, method.getName(),
344-
CodeFlow.createSignatureDescriptor(method), method.getDeclaringClass().isInterface());
343+
mv.visitMethodInsn(
344+
(isStaticMethod ? INVOKESTATIC : (isJava8DefaultMethod(method) ? INVOKEINTERFACE : INVOKEVIRTUAL)),
345+
classDesc, method.getName(), CodeFlow.createSignatureDescriptor(method),
346+
method.getDeclaringClass().isInterface());
345347
cf.pushDescriptor(this.exitTypeDescriptor);
346348

347349
if (this.originalPrimitiveExitTypeDescriptor != null) {
@@ -354,6 +356,11 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
354356
}
355357
}
356358

359+
private static boolean isJava8DefaultMethod(Method method) {
360+
return (method.getDeclaringClass().isInterface() && Modifier.isPublic(method.getModifiers()) &&
361+
!Modifier.isAbstract(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()));
362+
}
363+
357364

358365
private class MethodValueRef implements ValueRef {
359366

0 commit comments

Comments
 (0)