Search code examples
javaspringspring-integrationspring-el

SpelParseException on setting key of MessageHeader to 'NEW' in Spring Integration


Below code is setting 'NEW' key of MessageHeader in Spring Integration 2.2.6.

public Message<String> getFlow() {
    return MessageBuilder.withPayload("demo").setHeader("NEW", "NEW").build();
}

Below code retreives the value of 'NEW' key from header in the SI configuration file.

<jdbc:outbound-gateway
query="select name from emp where status=:headers[NEW]"
row-mapper="empMapper" data-source="dataSource"
max-rows-per-poll="100000" />

'NEW' header is set as shown in the below logs.

[Headers={timestamp=1399978938970, id=777bb8ba-04b6-4408-9d60-18c9711375cc, NEW=NEW}]

However, getting below exception:

org.springframework.expression.spel.SpelParseException: EL1043E:(pos 11): Unexpected token.  Expected 'identifier' but was 'rsquare(])'

It is resolved by changing key of MessageHeader from 'NEW' to 'STATUS_NEW' as shown below:

public Message<String> getFlow() {
    return MessageBuilder.withPayload("demo").setHeader("STATUS_NEW", "NEW").build();
}

<jdbc:outbound-gateway
query="select name from emp where status=:headers[STATUS_NEW]"
row-mapper="empMapper" data-source="dataSource"
max-rows-per-poll="100000" />

Is this the bug in SpEL or there are some restrictions in using names for key in MessageHeader?


Solution

  • It's not an issue of Spring Integration. It is general SpEL restriction. It is difficult to find it, but I digged it from debug:

    private boolean maybeEatConstructorReference() {
            if (peekIdentifierToken("new")) {
    ...
    

    and the code of that method:

    private boolean peekIdentifierToken(String identifierString) {
            if (!moreTokens()) {
                return false;
            }
            Token t = peekToken();
            return t.kind==TokenKind.IDENTIFIER && t.stringValue().equalsIgnoreCase(identifierString);
    }
    

    As you see equalsIgnoreCase does the stuff here.

    Not sure that it is appropriate to mark it as a bug for SpEL, but anyway it is restriction and you should use different identifier. Or try this syntax:

    select name from emp where status=:headers.NEW
    

    The bean property accessor, not map.

    Restricted tokens:

    • and
    • or
    • new
    • true
    • false