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