Skip to content

Commit 1a2186e

Browse files
committed
Attempt to fix lambda error detection on JDK 9
Update `LambdaSafe` to also detect `ClassCastException` messages that start with "module/name". See gh-11584
1 parent c90a5a9 commit 1a2186e

File tree

1 file changed

+34
-2
lines changed
  • spring-boot-project/spring-boot/src/main/java/org/springframework/boot/util

1 file changed

+34
-2
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/util/LambdaSafe.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.util;
1818

19+
import java.lang.reflect.Method;
1920
import java.util.Collection;
2021
import java.util.Optional;
2122
import java.util.function.Consumer;
@@ -30,6 +31,7 @@
3031
import org.springframework.core.ResolvableType;
3132
import org.springframework.util.Assert;
3233
import org.springframework.util.ClassUtils;
34+
import org.springframework.util.ReflectionUtils;
3335

3436
/**
3537
* Utility that can be used to invoke lambdas in a safe way. Primarily designed to help
@@ -41,6 +43,17 @@
4143
*/
4244
public final class LambdaSafe {
4345

46+
private static final Method CLASS_GET_MODULE;
47+
48+
private static final Method MODULE_GET_NAME;
49+
50+
static {
51+
CLASS_GET_MODULE = ReflectionUtils.findMethod(Class.class, "getModule");
52+
MODULE_GET_NAME = (CLASS_GET_MODULE == null ? null
53+
: ReflectionUtils.findMethod(CLASS_GET_MODULE.getReturnType(),
54+
"getName"));
55+
}
56+
4457
private LambdaSafe() {
4558
}
4659

@@ -164,12 +177,31 @@ private boolean isLambdaGenericProblem(ClassCastException ex) {
164177
}
165178

166179
private boolean startsWithArgumentClassName(String message) {
167-
Predicate<Object> startsWith = (argument) -> argument != null
168-
&& message.startsWith(argument.getClass().getName());
180+
Predicate<Object> startsWith = (argument) -> startsWithArgumentClassName(
181+
message, argument);
169182
return startsWith.test(this.argument)
170183
|| Stream.of(this.additionalArguments).anyMatch(startsWith);
171184
}
172185

186+
private boolean startsWithArgumentClassName(String message, Object argument) {
187+
if (argument == null) {
188+
return false;
189+
}
190+
Class<? extends Object> argumentType = argument.getClass();
191+
if (message.startsWith(argumentType.getName())) {
192+
return true;
193+
}
194+
if (CLASS_GET_MODULE != null) {
195+
Object module = ReflectionUtils.invokeMethod(CLASS_GET_MODULE,
196+
argumentType);
197+
Object moduleName = ReflectionUtils.invokeMethod(MODULE_GET_NAME, module);
198+
if (message.startsWith(moduleName + "/" + argumentType.getName())) {
199+
return true;
200+
}
201+
}
202+
return false;
203+
}
204+
173205
private void logNonMachingType(C callback, ClassCastException ex) {
174206
if (this.logger.isDebugEnabled()) {
175207
Class<?> expectedType = ResolvableType.forClass(this.callbackType)

0 commit comments

Comments
 (0)