尝试使用elvis运算符编译表达式时,Spring SPEL评估会抛出ArrayIndexOutOfBoundsException

时间:2018-03-23 09:51:52

标签: spring spring-el

有人可以解释为什么在这种情况下抛出异常:

@Test
public void spel_elvis_operator_test() {
    String time1 = "time1";
    String time2 = "time2";

    String spelExpression = String.format("get('%s') ?: get('%s')", time1, time2);

    Expression expression = new SpelExpressionParser(new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null))
            .parseExpression(spelExpression);

    Map<String, Object> data = new HashMap<>();
    data.put(time1, 1000L);
    data.put(time2, 2000L);

    // execute first time - interprets the expression
    assertThat(expression.getValue(new StandardEvaluationContext(data), Long.class)).isEqualTo(1000L);

    data.remove(time1);

    // execute second time - tries to compile expression
    assertThat(expression.getValue(new StandardEvaluationContext(data), Long.class)).isEqualTo(2000L);
}

当我运行此测试时,我得到了这个例外:

java.lang.ArrayIndexOutOfBoundsException: -1

at org.springframework.asm.Frame.merge(Frame.java:1501)
at org.springframework.asm.Frame.merge(Frame.java:1478)
at org.springframework.asm.MethodWriter.visitMaxs(MethodWriter.java:1516)
at org.springframework.expression.spel.standard.SpelCompiler.createExpressionClass(SpelCompiler.java:176)
at org.springframework.expression.spel.standard.SpelCompiler.compile(SpelCompiler.java:105)
at org.springframework.expression.spel.standard.SpelExpression.compileExpression(SpelExpression.java:467)
at org.springframework.expression.spel.standard.SpelExpression.checkCompile(SpelExpression.java:437)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300)

我正在尝试使用已编译的SPEL表达式进行动态数据过滤,我觉得我正在玩俄语轮盘...

1 个答案:

答案 0 :(得分:0)

听起来像个臭虫。看起来这种类型的表达式是不可编译的,因此必须使用后退到解释模式。

这个适用于我:

String spelExpression = String.format("get('%s') != null ? get('%s') : get('%s')", time1, time1, time2);

我的意思是我使用经典的Java三元运算符而不是elvis。

随意就此事提出JIRA:https://jira.spring.io/browse/SPR