Overview

While implementing #32613, I noticed that SpEL currently does not support compilation of expressions that provide an Integer value when indexing into an array or list.

Standard evaluation of such operations works fine, but when we attempt to compile the expression into bytecode, that fails because an Integer cannot be automatically unboxed to an int.

Examples

In both of the following tests, the last invocation of SpelCompiler.compile(...) fails with java.lang.VerifyError: Bad type on operand stack because #index (an Integer) cannot be auto-unboxed in bytecode.

@Test
void indexIntoArray() {
    SpelExpressionParser parser = new SpelExpressionParser();
    StandardEvaluationContext context = new StandardEvaluationContext();
    context.setVariable("array", new int[] {1, 2, 3, 4});

    Expression expression = parser.parseExpression("#array[2]");
    assertThat(expression.getValue(context)).isEqualTo(3);
    assertThat(SpelCompiler.compile(expression)).isTrue();

    context.setVariable("index", 2);
    expression = parser.parseExpression("#array[#index]");
    assertThat(expression.getValue(context)).isEqualTo(3);
    assertThat(SpelCompiler.compile(expression)).isTrue();
}
@Test
void indexIntoList() {
    SpelExpressionParser parser = new SpelExpressionParser();
    StandardEvaluationContext context = new StandardEvaluationContext();
    context.setVariable("list", List.of(1, 2, 3, 4));

    Expression expression = parser.parseExpression("#list[2]");
    assertThat(expression.getValue(context)).isEqualTo(3);
    assertThat(SpelCompiler.compile(expression)).isTrue();

    context.setVariable("index", 2);
    expression = parser.parseExpression("#list[#index]");
    assertThat(expression.getValue(context)).isEqualTo(3);
    assertThat(SpelCompiler.compile(expression)).isTrue();
}

Related Issues

  • 32613