|
16 | 16 |
|
17 | 17 | package org.springframework.boot.util;
|
18 | 18 |
|
| 19 | +import java.lang.reflect.Method; |
19 | 20 | import java.util.Collection;
|
20 | 21 | import java.util.Optional;
|
21 | 22 | import java.util.function.Consumer;
|
|
30 | 31 | import org.springframework.core.ResolvableType;
|
31 | 32 | import org.springframework.util.Assert;
|
32 | 33 | import org.springframework.util.ClassUtils;
|
| 34 | +import org.springframework.util.ReflectionUtils; |
33 | 35 |
|
34 | 36 | /**
|
35 | 37 | * Utility that can be used to invoke lambdas in a safe way. Primarily designed to help
|
|
41 | 43 | */
|
42 | 44 | public final class LambdaSafe {
|
43 | 45 |
|
| 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 | + |
44 | 57 | private LambdaSafe() {
|
45 | 58 | }
|
46 | 59 |
|
@@ -164,12 +177,31 @@ private boolean isLambdaGenericProblem(ClassCastException ex) {
|
164 | 177 | }
|
165 | 178 |
|
166 | 179 | 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); |
169 | 182 | return startsWith.test(this.argument)
|
170 | 183 | || Stream.of(this.additionalArguments).anyMatch(startsWith);
|
171 | 184 | }
|
172 | 185 |
|
| 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 | + |
173 | 205 | private void logNonMachingType(C callback, ClassCastException ex) {
|
174 | 206 | if (this.logger.isDebugEnabled()) {
|
175 | 207 | Class<?> expectedType = ResolvableType.forClass(this.callbackType)
|
|
0 commit comments