Browse Source

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 81fde5ec41)
pull/23430/head
Sam Brannen 6 years ago
parent
commit
f0e69e06b7
  1. 8
      spring-core/src/main/java/org/springframework/core/MethodParameter.java

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

@ -725,11 +725,19 @@ public class MethodParameter { @@ -725,11 +725,19 @@ public class MethodParameter {
protected static int findParameterIndex(Parameter parameter) {
Executable executable = parameter.getDeclaringExecutable();
Parameter[] allParams = executable.getParameters();
// Try first with identity checks for greater performance.
for (int i = 0; i < allParams.length; i++) {
if (parameter == allParams[i]) {
return i;
}
}
// Potentially try again with object equality checks in order to avoid race
// conditions while invoking java.lang.reflect.Executable.getParameters().
for (int i = 0; i < allParams.length; i++) {
if (parameter.equals(allParams[i])) {
return i;
}
}
throw new IllegalArgumentException("Given parameter [" + parameter +
"] does not match any parameter in the declaring executable");
}

Loading…
Cancel
Save