Giulio Quaresima opened SPR-17294 and commented
When I use the Safe Navigation operator my expectation is that it is always safe to evaluate an expression with null values. But in some contexts I get the SpelEvaluationException with the message "EL1012E:(pos 11): Cannot index into a null value".
See the example attached.
Affects: 4.3.19
Attachments: - SpringSpelBug.java (1.74 kB)
Comment From: spring-projects-issues
Andy Clement commented
This is actually working as designed right now. The expression from the test program is
vocabulary?.map['bye']
There are actually two dereferences there:
* finding the map
property on the vocabulary
object
* finding the value of the 'bye'
key in the map
The exception: EL1012E: Cannot index into a null value
has position 15
which is the position of the second dereference [..]
- the problem here is that the first dereference is nullsafe but the second is not. Hence the exception. If the expression is changed to vocabulary?.map?.get('bye')
then it works as expected, the value is null
when vocabulary is not set. Without thinking too deeply, supporting ?[..]
feels doable if we wanted to extend Spel indexing for this case - because some uses of [..]
cannot be translated to a method call (like get), for example an array.
Comment From: spring-projects-issues
Giulio Quaresima commented
I thank you very much, I had not been understanding well the operator's semantics before: maybe its documentation is not so clear about these details. Actually, reading the documentation, the natural interpretation to me was that if an expression contained a reference to a null
property marked with ?
, the evaluation would stop there, without visiting the child nodes, whatever was in the rest of the expression.
Consider a such class:
public class Bob
{
public String name = "Bob";
public Integer age = 14;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Integer getAge()
{
return age;
}
public void setAge(Integer age)
{
this.age = age;
}
}
and an evaluation context with a bob
property of type Bob
, with null
value. If we try to evaluate expressions such as bob?.name
, bob?.age
or bob?.getAge()
we obtain a null
value, as expected. But if we try to evaluate, for example, bob?.age.intValue()
, we get an EL1011E
error: "Attempted to call method intValue() on null context object". IMHO, this behaviour makes the operator inconsistent or, at least, error-prone and much less useful than the expected-by-me behaviour. Consider, also, that the JSP's EL works exactly as I mean: if a property in an expression is null
, its evaluation returns null
without visiting any child property, at any depth.
Comment From: spring-projects-issues
Juan Domínguez González commented
Just a note on this: supporting ?[..]
seems related to #21468
Comment From: spring-projects-issues
Andy Clement commented
Yes, after further thinking, I think we could say for a compound expression the use of a null safe mechanism in the middle terminates the entire expression with null. (as in change the implementation to behave this way)
Comment From: aantono
:bump Any updates on fixing this?
Comment From: sbrannen
@aclement, ping.
Comment From: sbrannen
In order to avoid introducing additional complexity in the implementation of the Spring Expression Language, we have decided not to resolve an entire compound expression to null
when the null-safe operator is used on a preceding node but not on subsequent nodes.
In other words, use of the null-safe navigation operator is required on all nodes in a compound expression, which aligns with the behavior of other languages such as Groovy.
I am therefore repurposing this ticket to document the current behavior.
Furthermore, please note that we will introduce a null-safe index operator in Spring Framework 6.2.
Related Issues
-
29847
-
32208