Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpEL: static access via the type function fails if the class implements Map [SPR-9861] #14494

Closed
spring-projects-issues opened this issue Oct 5, 2012 · 1 comment
Assignees
Labels
in: core status: backported status: duplicate
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 5, 2012

Sam Brannen opened SPR-9861 and commented

Status Quo

When using SpEL's type function T to access a static constant, evaluation of the expression fails if the class referenced by the T function implements java.util.Map.

For example, the following SpEL expression (taken from an excerpt from a project using Spring Integration) fails:

<header name="#{T(org.springframework.integration.MessageHeaders).CORRELATION_ID}" value="foo" />

... with the following exception:

Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.util.Map 
        at org.springframework.context.expression.MapAccessor.canRead(MapAccessor.java:37) 
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:190)

        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)

        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) 
        at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93) 
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88) 
        at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:139)

        ... 47 more

Analysis

The reason for the above exception is that Spring Integration's MessageHeaders class implements java.util.Map. Thus the SpEL MapAccessor is added to the list of candidate property accessors to try in PropertyOrFieldReference.getPropertyAccessorsToTry(Class<?>, ExpressionState), and MapAccessor ends up in the candidate list before ReflectivePropertyAccessor.

So, when the expression is evaluated, it fails since the T() function returns a class instead of a Map instance. In other words, the MapAccessor assumes it is being passed an instance of java.util.Map, when it in fact receives an instance of java.lang.Class (i.e., the class reference returned by the T() function).

In summary, MapAccessor obviously cannot be used to access static members. Thus the current implementation is completely broken in that the building of the candidate property accessor list does not take into account that the eventual property access may be static.


Deliverables

  1. Ensure that static members (i.e., constants) can be accessed in SpEL expressions using the T() function when the class passed to the T() function implements java.util.Map.

Affects: 3.0 GA

Issue Links:

  • #16232 Referencing static field of class that extends Map in expression language causes class cast exception ("duplicates")

Backported to: 3.2.9

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 5, 2012

Sam Brannen commented

Andy Clement,

I have added you as a watcher to this issue.

Please feel free to make comments and/or assign the issue to yourself if you have time to tackle it.

Thanks,

Sam

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core status: backported status: duplicate
Projects
None yet
Development

No branches or pull requests

2 participants