diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java index a00748e04c..02d01ae5f1 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java @@ -17,12 +17,13 @@ package org.springframework.expression.spel.support; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -107,7 +108,7 @@ public class ReflectiveMethodResolver implements MethodResolver { try { TypeConverter typeConverter = context.getTypeConverter(); Class type = (targetObject instanceof Class ? (Class) targetObject : targetObject.getClass()); - List methods = new ArrayList(Arrays.asList(getMethods(type, targetObject))); + List methods = new ArrayList((getMethods(type, targetObject))); // If a filter is registered for this type, call it MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); @@ -216,14 +217,22 @@ public class ReflectiveMethodResolver implements MethodResolver { } } - private Method[] getMethods(Class type, Object targetObject) { + private Collection getMethods(Class type, Object targetObject) { if (targetObject instanceof Class) { - Set methods = new HashSet(); - methods.addAll(Arrays.asList(getMethods(type))); - methods.addAll(Arrays.asList(getMethods(targetObject.getClass()))); - return methods.toArray(new Method[methods.size()]); + Set result = new LinkedHashSet(); + result.addAll(Arrays.asList(getMethods(targetObject.getClass()))); + // Add these also so that static result are invocable on the type: e.g. Float.valueOf(..) + Method[] methods = getMethods(type); + for (Method method : methods) { + if (Modifier.isStatic(method.getModifiers())) { + result.add(method); + } + } + return result; + } + else { + return Arrays.asList(getMethods(type)); } - return getMethods(type); } /** 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 b8ee8aa953..aed9313c6a 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 @@ -1208,7 +1208,7 @@ public class SpelReproTests extends AbstractExpressionTests { @Override public Class[] getSpecificTargetClasses() { - return new Class[] { ContextObject.class }; + return new Class[] {ContextObject.class}; } @Override @@ -1278,7 +1278,7 @@ public class SpelReproTests extends AbstractExpressionTests { protected Method[] getMethods(Class type) { try { return new Method[] { - Integer.class.getDeclaredMethod("parseInt", new Class[] { String.class, Integer.TYPE }) }; + Integer.class.getDeclaredMethod("parseInt", new Class[] {String.class, Integer.TYPE})}; } catch (NoSuchMethodException ex) { return new Method[0]; @@ -1878,6 +1878,14 @@ public class SpelReproTests extends AbstractExpressionTests { assertEquals("child1", exp.getValue(context)); } + @Test + public void SPR12502() throws Exception { + SpelExpressionParser parser = new SpelExpressionParser(); + Expression expression = parser.parseExpression("#root.getClass().getName()"); + assertEquals(UnnamedUser.class.getName(), expression.getValue(new UnnamedUser())); + assertEquals(NamedUser.class.getName(), expression.getValue(new NamedUser())); + } + private static enum ABC { A, B, C } @@ -2151,4 +2159,16 @@ public class SpelReproTests extends AbstractExpressionTests { } } + + public static class UnnamedUser { + } + + + public static class NamedUser { + + public String getName() { + return "foo"; + } + } + }