Skip to content

Commit 9ef0bdc

Browse files
committed
Consistent resolution of Class methods and static methods
Issue: SPR-12502
1 parent 1de7151 commit 9ef0bdc

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
package org.springframework.expression.spel.support;
1818

1919
import java.lang.reflect.Method;
20+
import java.lang.reflect.Modifier;
2021
import java.util.ArrayList;
2122
import java.util.Arrays;
23+
import java.util.Collection;
2224
import java.util.Collections;
2325
import java.util.Comparator;
2426
import java.util.HashMap;
25-
import java.util.HashSet;
2627
import java.util.LinkedHashSet;
2728
import java.util.List;
2829
import java.util.Map;
@@ -107,7 +108,7 @@ public MethodExecutor resolve(EvaluationContext context, Object targetObject, St
107108
try {
108109
TypeConverter typeConverter = context.getTypeConverter();
109110
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
110-
List<Method> methods = new ArrayList<Method>(Arrays.asList(getMethods(type, targetObject)));
111+
List<Method> methods = new ArrayList<Method>((getMethods(type, targetObject)));
111112

112113
// If a filter is registered for this type, call it
113114
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
@@ -216,14 +217,22 @@ else if (matchRequiringConversion != null) {
216217
}
217218
}
218219

219-
private Method[] getMethods(Class<?> type, Object targetObject) {
220+
private Collection<Method> getMethods(Class<?> type, Object targetObject) {
220221
if (targetObject instanceof Class) {
221-
Set<Method> methods = new HashSet<Method>();
222-
methods.addAll(Arrays.asList(getMethods(type)));
223-
methods.addAll(Arrays.asList(getMethods(targetObject.getClass())));
224-
return methods.toArray(new Method[methods.size()]);
222+
Set<Method> result = new LinkedHashSet<Method>();
223+
result.addAll(Arrays.asList(getMethods(targetObject.getClass())));
224+
// Add these also so that static result are invocable on the type: e.g. Float.valueOf(..)
225+
Method[] methods = getMethods(type);
226+
for (Method method : methods) {
227+
if (Modifier.isStatic(method.getModifiers())) {
228+
result.add(method);
229+
}
230+
}
231+
return result;
232+
}
233+
else {
234+
return Arrays.asList(getMethods(type));
225235
}
226-
return getMethods(type);
227236
}
228237

229238
/**

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,7 @@ public boolean canWrite(EvaluationContext context, Object target, String name) t
12081208

12091209
@Override
12101210
public Class<?>[] getSpecificTargetClasses() {
1211-
return new Class[] { ContextObject.class };
1211+
return new Class<?>[] {ContextObject.class};
12121212
}
12131213

12141214
@Override
@@ -1278,7 +1278,7 @@ public void customStaticFunctions_SPR9038() {
12781278
protected Method[] getMethods(Class<?> type) {
12791279
try {
12801280
return new Method[] {
1281-
Integer.class.getDeclaredMethod("parseInt", new Class[] { String.class, Integer.TYPE }) };
1281+
Integer.class.getDeclaredMethod("parseInt", new Class<?>[] {String.class, Integer.TYPE})};
12821282
}
12831283
catch (NoSuchMethodException ex) {
12841284
return new Method[0];
@@ -1878,6 +1878,14 @@ public void SPR9735() {
18781878
assertEquals("child1", exp.getValue(context));
18791879
}
18801880

1881+
@Test
1882+
public void SPR12502() throws Exception {
1883+
SpelExpressionParser parser = new SpelExpressionParser();
1884+
Expression expression = parser.parseExpression("#root.getClass().getName()");
1885+
assertEquals(UnnamedUser.class.getName(), expression.getValue(new UnnamedUser()));
1886+
assertEquals(NamedUser.class.getName(), expression.getValue(new NamedUser()));
1887+
}
1888+
18811889

18821890
private static enum ABC { A, B, C }
18831891

@@ -2151,4 +2159,16 @@ public List<Item> subList(int fromIndex, int toIndex) {
21512159
}
21522160
}
21532161

2162+
2163+
public static class UnnamedUser {
2164+
}
2165+
2166+
2167+
public static class NamedUser {
2168+
2169+
public String getName() {
2170+
return "foo";
2171+
}
2172+
}
2173+
21542174
}

0 commit comments

Comments
 (0)