Skip to content

Commit 4660e61

Browse files
committed
Consistent resolution of Class methods and static methods
Issue: SPR-12502 (cherry picked from commit 9ef0bdc)
1 parent dfc7972 commit 4660e61

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 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.
@@ -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);
@@ -201,14 +202,22 @@ else if (matchRequiringConversion != null) {
201202
}
202203
}
203204

204-
private Method[] getMethods(Class<?> type, Object targetObject) {
205+
private Collection<Method> getMethods(Class<?> type, Object targetObject) {
205206
if (targetObject instanceof Class) {
206-
Set<Method> methods = new HashSet<Method>();
207-
methods.addAll(Arrays.asList(getMethods(type)));
208-
methods.addAll(Arrays.asList(getMethods(targetObject.getClass())));
209-
return methods.toArray(new Method[methods.size()]);
207+
Set<Method> result = new LinkedHashSet<Method>();
208+
result.addAll(Arrays.asList(getMethods(targetObject.getClass())));
209+
// Add these also so that static result are invocable on the type: e.g. Float.valueOf(..)
210+
Method[] methods = getMethods(type);
211+
for (Method method : methods) {
212+
if (Modifier.isStatic(method.getModifiers())) {
213+
result.add(method);
214+
}
215+
}
216+
return result;
217+
}
218+
else {
219+
return Arrays.asList(getMethods(type));
210220
}
211-
return getMethods(type);
212221
}
213222

214223
/**

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];
@@ -1877,6 +1877,14 @@ public void SPR9735() {
18771877
assertEquals("child1", exp.getValue(context));
18781878
}
18791879

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

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

@@ -2149,4 +2157,16 @@ public List<Item> subList(int fromIndex, int toIndex) {
21492157
}
21502158
}
21512159

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

0 commit comments

Comments
 (0)