SpEL expression fails to evaluate on second String literal value processing when in SpelCompilerMode.IMMEDIATE mode

480 Views Asked by At

Using spring-expression version 5.1.5, trying to evaluate several values using pre-compiled SpEL expression, like in the following snippet:

    String expression = "T(java.time.LocalDateTime).parse(#root, T(java.time.format.DateTimeFormatter).ofPattern(\"M/d/yy H:mm\")).toEpochSecond(T(java.time.ZoneOffset).UTC) * 1000";
    Expression spelExpression = expressionParser.parseExpression(expression);

    assertEquals(1514768400000L, (long)spelExpression.getValue("1/1/18 1:00"));
    assertEquals(1514854800000L, (long)spelExpression.getValue("1/2/18 1:00"));

It fails with

java.lang.IllegalStateException: Failed to instantiate CompiledExpression

    at org.springframework.expression.spel.standard.SpelCompiler.compile(SpelCompiler.java:111)
    at org.springframework.expression.spel.standard.SpelExpression.compileExpression(SpelExpression.java:511)
    at org.springframework.expression.spel.standard.SpelExpression.checkCompile(SpelExpression.java:481)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:202)
...
Caused by: java.lang.VerifyError: (class: spel/Ex2, method: getValue signature: (Ljava/lang/Object;Lorg/springframework/expression/EvaluationContext;)Ljava/lang/Object;) Illegal type in constant pool
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
    at java.lang.Class.getConstructor0(Class.java:3075)
    at java.lang.Class.getDeclaredConstructor(Class.java:2178)
    at org.springframework.util.ReflectionUtils.accessibleConstructor(ReflectionUtils.java:530)
    at org.springframework.expression.spel.standard.SpelCompiler.compile(SpelCompiler.java:108)
...

The same works well in SpelCompilerMode.OFF mode.

Found a discussion on something similar: https://github.com/spring-projects/spring-framework/issues/20739

But it is about proxy support and should have also been fixed by 5.1.5.

Is there a way to use pre-compiled mode in my case? Is the usage of #root and passing a String instead of a context object a problem?

Same situation with the recent 5.1.10.RELEASE version.

0

There are 0 best solutions below