Skip to content

Commit f0e69e0

Browse files
committed
Ensure that MethodParameter.findParameterIndex() is thread-safe
Prior to this commit, parallel invocations of MethodParameter.findParameterIndex() (invoked indirectly via SynthesizingMethodParameter.forParameter() and MethodParameter.forParameter()) could intermittently lead to an IllegalArgumentException being thrown due to a race condition in the internal implementation of the JDK's java.lang.reflect.Executable.getParameters() method. This commit addresses this issue by introducing a fallback for-loop that iterates over the candidate parameters a second time using equality checks instead of identity checks. Issue: SPR-17534 (cherry-picked from commit 81fde5e)
1 parent cd67b28 commit f0e69e0

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

spring-core/src/main/java/org/springframework/core/MethodParameter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,11 +725,19 @@ public static MethodParameter forParameter(Parameter parameter) {
725725
protected static int findParameterIndex(Parameter parameter) {
726726
Executable executable = parameter.getDeclaringExecutable();
727727
Parameter[] allParams = executable.getParameters();
728+
// Try first with identity checks for greater performance.
728729
for (int i = 0; i < allParams.length; i++) {
729730
if (parameter == allParams[i]) {
730731
return i;
731732
}
732733
}
734+
// Potentially try again with object equality checks in order to avoid race
735+
// conditions while invoking java.lang.reflect.Executable.getParameters().
736+
for (int i = 0; i < allParams.length; i++) {
737+
if (parameter.equals(allParams[i])) {
738+
return i;
739+
}
740+
}
733741
throw new IllegalArgumentException("Given parameter [" + parameter +
734742
"] does not match any parameter in the declaring executable");
735743
}

0 commit comments

Comments
 (0)