Skip to content

Commit

Permalink
Ensure that MethodParameter.findParameterIndex() is thread-safe
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sbrannen committed Nov 23, 2018
1 parent aa7f69a commit 81fde5e
Showing 1 changed file with 8 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -733,11 +733,19 @@ public static MethodParameter forParameter(Parameter parameter) {
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");
}
Expand Down

0 comments on commit 81fde5e

Please sign in to comment.