Skip to content

Commit 634284e

Browse files
committed
Use bridge methods in ReflectiveMethodResolver
Update ReflectiveMethodResolver to consider bridge methods. Issue: SPR-10210
1 parent d442c40 commit 634284e

File tree

6 files changed

+113
-18
lines changed

6 files changed

+113
-18
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,13 +19,16 @@
1919
import java.lang.reflect.Method;
2020
import java.util.ArrayList;
2121
import java.util.Arrays;
22+
import java.util.Collections;
2223
import java.util.Comparator;
2324
import java.util.HashMap;
2425
import java.util.HashSet;
26+
import java.util.LinkedHashSet;
2527
import java.util.List;
2628
import java.util.Map;
2729
import java.util.Set;
2830

31+
import org.springframework.core.BridgeMethodResolver;
2932
import org.springframework.core.MethodParameter;
3033
import org.springframework.core.convert.TypeDescriptor;
3134
import org.springframework.expression.AccessException;
@@ -37,7 +40,6 @@
3740
import org.springframework.expression.TypeConverter;
3841
import org.springframework.expression.spel.SpelEvaluationException;
3942
import org.springframework.expression.spel.SpelMessage;
40-
import org.springframework.util.CollectionUtils;
4143

4244
/**
4345
* Reflection-based {@link MethodResolver} used by default in
@@ -92,42 +94,38 @@ public MethodExecutor resolve(EvaluationContext context, Object targetObject, St
9294
try {
9395
TypeConverter typeConverter = context.getTypeConverter();
9496
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
95-
Method[] methods = getMethods(type, targetObject);
97+
List<Method> methods = new ArrayList<Method>(Arrays.asList(getMethods(type, targetObject)));
9698

9799
// If a filter is registered for this type, call it
98100
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
99101
if (filter != null) {
100-
List<Method> methodsForFiltering = new ArrayList<Method>();
101-
for (Method method: methods) {
102-
methodsForFiltering.add(method);
103-
}
104-
List<Method> methodsFiltered = filter.filter(methodsForFiltering);
105-
if (CollectionUtils.isEmpty(methodsFiltered)) {
106-
methods = NO_METHODS;
107-
}
108-
else {
109-
methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]);
110-
}
102+
methods = filter.filter(methods);
111103
}
112104

113-
Arrays.sort(methods, new Comparator<Method>() {
105+
// Sort methods into a sensible order
106+
Collections.sort(methods, new Comparator<Method>() {
114107
public int compare(Method m1, Method m2) {
115108
int m1pl = m1.getParameterTypes().length;
116109
int m2pl = m2.getParameterTypes().length;
117110
return (new Integer(m1pl)).compareTo(m2pl);
118111
}
119112
});
120113

114+
// Resolve any bridge methods
115+
for (int i = 0; i < methods.size(); i++) {
116+
methods.set(i, BridgeMethodResolver.findBridgedMethod(methods.get(i)));
117+
}
118+
119+
// Remove duplicate methods (possible due to resolved bridge methods)
120+
methods = new ArrayList<Method>(new LinkedHashSet<Method>(methods));
121+
121122
Method closeMatch = null;
122123
int closeMatchDistance = Integer.MAX_VALUE;
123124
int[] argsToConvert = null;
124125
Method matchRequiringConversion = null;
125126
boolean multipleOptions = false;
126127

127128
for (Method method : methods) {
128-
if (method.isBridge()) {
129-
continue;
130-
}
131129
if (method.getName().equals(name)) {
132130
Class<?>[] paramTypes = method.getParameterTypes();
133131
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);

spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.junit.Assert.assertTrue;
2525
import static org.junit.Assert.fail;
2626

27+
import java.io.Serializable;
2728
import java.lang.reflect.Field;
2829
import java.lang.reflect.Method;
2930
import java.util.ArrayList;
@@ -1736,6 +1737,14 @@ public void SPR_10125() throws Exception {
17361737
assertThat(fromClass, is("interfaceValue"));
17371738
}
17381739

1740+
@Test
1741+
public void SPR_10210() throws Exception {
1742+
StandardEvaluationContext context = new StandardEvaluationContext();
1743+
context.setVariable("bridgeExample", new org.springframework.expression.spel.spr10210.D());
1744+
Expression parseExpression = parser.parseExpression("#bridgeExample.bridgetMethod()");
1745+
parseExpression.getValue(context);
1746+
}
1747+
17391748
public static class BooleanHolder {
17401749

17411750
private Boolean simpleProperty = true;
@@ -1796,4 +1805,5 @@ public static class StaticFinalImpl1 extends AbstractStaticFinal implements Stat
17961805

17971806
public static class StaticFinalImpl2 extends AbstractStaticFinal {
17981807
}
1808+
17991809
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.expression.spel.spr10210;
18+
19+
import org.springframework.expression.spel.spr10210.comp.B;
20+
import org.springframework.expression.spel.spr10210.infra.C;
21+
22+
abstract class A extends B<C> {
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.expression.spel.spr10210;
18+
19+
public class D extends A {
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.expression.spel.spr10210.comp;
18+
19+
import java.io.Serializable;
20+
21+
import org.springframework.expression.spel.spr10210.infra.C;
22+
23+
public class B<T extends C> implements Serializable {
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.expression.spel.spr10210.infra;
18+
19+
public interface C {
20+
}

0 commit comments

Comments
 (0)