-
Notifications
You must be signed in to change notification settings - Fork 37.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IncompatibleClassChangeError encountered on execution of compiled SPEL expressions #24357
Comments
I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference. |
Thanks for raising the issue. @Smahlatz, would you be interested in submitting a PR with your patch and your test? |
@sbrannen I would certainly be interested in submitting a PR, however my current terms of employment make this problematic. |
Understood.
Never mind: I've implemented a simplified version. |
I have confirmed that the following test case fails on Interestingly, the test only fails if the interface is import java.util.stream.IntStream;
import org.junit.jupiter.api.Test;
import org.springframework.core.Ordered;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelCompiler;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the {@link SpelCompiler}.
*
* @since 5.1.14
*/
class SpelCompilerTests {
@Test // gh-24357
void expressionCompilesWhenMethodComesFromPublicInterface() {
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
SpelExpressionParser parser = new SpelExpressionParser(config);
OrderedComponent component = new OrderedComponent();
Expression expression = parser.parseExpression("order");
// Evaluate the expression multiple times to ensure that it gets compiled.
IntStream.rangeClosed(1, 5).forEach(i -> assertThat(expression.getValue(component)).isEqualTo(42));
}
static class OrderedComponent implements Ordered {
@Override
public int getOrder() {
return 42;
}
}
} Whereas, the following JUnit 4 based test case passes against the import java.util.stream.IntStream;
import org.junit.Test;
import org.springframework.core.Ordered;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import static org.junit.Assert.assertEquals;
public class SpelCompilerTests {
@Test // gh-24357
public void expressionCompilesWhenMethodComesFromPublicInterface() {
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
SpelExpressionParser parser = new SpelExpressionParser(config);
OrderedComponent component = new OrderedComponent();
Expression expression = parser.parseExpression("order");
// Evaluate the expression multiple times to ensure that it gets compiled.
IntStream.rangeClosed(1, 5).forEach(i -> assertEquals(42, expression.getValue(component)));
}
static class OrderedComponent implements Ordered {
@Override
public int getOrder() {
return 42;
}
}
} |
@sbrannen Regarding the public interface - that's right - if not marked public, expression.isCompilable returns false and no compilation happens. |
Spring Framework 5.1.8 introduced a regression for the compilation of SpEL expressions referencing a method declared in an interface. An attempt to compile such an expression resulted in a SpelEvaluationException caused by an IncompatibleClassChangeError. This commit fixes this regression by adding explicit support in ReflectivePropertyAccessor.OptimalPropertyAccessor.generateCode() for methods declared in interfaces. Closes gh-24357
This has been fixed, to be included in 5.2.4 and backported to 5.1.14. Feel free to try out the fix in upcoming snapshot builds for those versions. |
Affects: 5.1.12, 5.2.2
Since this change in 5.1.8.RELEASE (#22242) we are witnessing failures in evaluation of compiled SpEL expressions.
The following test exposes the issue:
Running this results in the following exception:
The issue looks to be with the compilation - org.springframework.expression.spel.support.ReflectivePropertyAccessor.generateCode contains the following:
As we now are potentially referencing an interface, the following change fixes the issue:
This has been tested against Oracle JDK 8u231 and spring-expression 5.1.12.RELEASE and 5.2.2.RELEASE. The issue is not encountered in spring-expression 5.1.7 and below.
The text was updated successfully, but these errors were encountered: