From 107fafbcc5d93284e5098686cc287c41280ee263 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 15 Nov 2012 17:22:45 -0800 Subject: [PATCH] Do not consider bridge methods in SpEL properties Modify ReflectivePropertyAccessor so that it no longer considers bridge methods when finding getters or setters. This should help to prevent subtle errors that can occur when particular JDK implementations happen to return bridge methods before non-bridge methods when calling Class.getMethods() Issue: SPR-9994 --- .../support/ReflectivePropertyAccessor.java | 6 ++--- .../expression/spel/SpelReproTests.java | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 0dd11d23ca..031a716a99 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -320,7 +320,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { // Try "get*" method... String getterName = "get" + propertyWriteMethodSuffix; for (Method method : ms) { - if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && + if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { return method; } @@ -328,7 +328,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { // Try "is*" method... getterName = "is" + propertyWriteMethodSuffix; for (Method method : ms) { - if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && + if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 && boolean.class.equals(method.getReturnType()) && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { return method; @@ -344,7 +344,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { Method[] methods = clazz.getMethods(); String setterName = "set" + StringUtils.capitalize(propertyName); for (Method method : methods) { - if (method.getName().equals(setterName) && method.getParameterTypes().length == 1 && + if (!method.isBridge() && method.getName().equals(setterName) && method.getParameterTypes().length == 1 && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { return method; } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java index b38c719896..276fbff325 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java @@ -50,6 +50,10 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.expression.spel.support.StandardTypeLocator; import org.springframework.expression.spel.testresources.le.div.mod.reserved.Reserver; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isA; import static org.junit.Assert.*; /** @@ -1633,6 +1637,25 @@ public class SpelReproTests extends ExpressionTestCase { } } + @Test + public void testBridgeMethods_SPR_9994() throws Exception { + ReflectivePropertyAccessor accessor = new ReflectivePropertyAccessor(); + StandardEvaluationContext context = new StandardEvaluationContext(); + Object target = new GenericImplementation(); + TypedValue value = accessor.read(context, target , "property"); + assertEquals(Integer.class, value.getTypeDescriptor().getType()); + } + + private static interface GenericInterface { + public T getProperty(); + } + + private static class GenericImplementation implements GenericInterface { + public Integer getProperty() { + return null; + } + } + }