Skip to content

Commit ad91fa6

Browse files
committed
SpEL support for static finals on interfaces
Update ReflectivePropertyAccessor to search for fields on super classes and implemented interfaces. Although the javadoc Class.getFields() implies that all public fields of class should be returned SpelReproTests demonstrates that this is not always the case. Issue: SPR-10125
1 parent bff36fb commit ad91fa6

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,18 @@ protected Field findField(String name, Class<?> clazz, boolean mustBeStatic) {
383383
return field;
384384
}
385385
}
386+
if(clazz.getSuperclass() != null) {
387+
Field field = findField(name, clazz.getSuperclass(), mustBeStatic);
388+
if(field != null) {
389+
return field;
390+
}
391+
}
392+
for (Class<?> implementedInterface : clazz.getInterfaces()) {
393+
Field field = findField(name, implementedInterface, mustBeStatic);
394+
if(field != null) {
395+
return field;
396+
}
397+
}
386398
return null;
387399
}
388400

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package org.springframework.expression.spel;
1818

19+
import static org.hamcrest.Matchers.is;
1920
import static org.junit.Assert.assertEquals;
2021
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertThat;
2123
import static org.junit.Assert.assertTrue;
2224
import static org.junit.Assert.fail;
2325

@@ -1720,6 +1722,15 @@ private void doTestSpr10146(String expression, String expectedMessage) {
17201722
new SpelExpressionParser().parseExpression(expression);
17211723
}
17221724

1725+
@Test
1726+
public void SPR_10125() throws Exception {
1727+
StandardEvaluationContext context = new StandardEvaluationContext();
1728+
String fromInterface = parser.parseExpression("T("+StaticFinalImpl1.class.getName()+").VALUE").getValue(context, String.class);
1729+
assertThat(fromInterface, is("interfaceValue"));
1730+
String fromClass = parser.parseExpression("T("+StaticFinalImpl2.class.getName()+").VALUE").getValue(context, String.class);
1731+
assertThat(fromClass, is("interfaceValue"));
1732+
}
1733+
17231734
public static class BooleanHolder {
17241735

17251736
private Boolean simpleProperty = true;
@@ -1768,4 +1779,16 @@ public static class OnlyBridgeMethod extends PackagePrivateClassWithGetter {
17681779

17691780
}
17701781

1782+
public static interface StaticFinal {
1783+
public static final String VALUE = "interfaceValue";
1784+
}
1785+
1786+
public abstract static class AbstractStaticFinal implements StaticFinal {
1787+
}
1788+
1789+
public static class StaticFinalImpl1 extends AbstractStaticFinal implements StaticFinal {
1790+
}
1791+
1792+
public static class StaticFinalImpl2 extends AbstractStaticFinal {
1793+
}
17711794
}

0 commit comments

Comments
 (0)