Browse Source

Leniently ignore unsupported pointcut expression

See gh-32793
pull/32864/head
Juergen Hoeller 2 years ago
parent
commit
a4135bac5c
  1. 23
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java
  2. 15
      spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java

23
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java

@ -170,25 +170,30 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override @Override
public ClassFilter getClassFilter() { public ClassFilter getClassFilter() {
obtainPointcutExpression(); checkExpression();
return this; return this;
} }
@Override @Override
public MethodMatcher getMethodMatcher() { public MethodMatcher getMethodMatcher() {
obtainPointcutExpression(); checkExpression();
return this; return this;
} }
/** /**
* Check whether this pointcut is ready to match, * Check whether this pointcut is ready to match.
* lazily building the underlying AspectJ pointcut expression.
*/ */
private PointcutExpression obtainPointcutExpression() { private void checkExpression() {
if (getExpression() == null) { if (getExpression() == null) {
throw new IllegalStateException("Must set property 'expression' before attempting to match"); throw new IllegalStateException("Must set property 'expression' before attempting to match");
} }
}
/**
* Lazily build the underlying AspectJ pointcut expression.
*/
private PointcutExpression obtainPointcutExpression() {
if (this.pointcutExpression == null) { if (this.pointcutExpression == null) {
this.pointcutClassLoader = determinePointcutClassLoader(); this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader); this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
@ -265,10 +270,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override @Override
public boolean matches(Class<?> targetClass) { public boolean matches(Class<?> targetClass) {
PointcutExpression pointcutExpression = obtainPointcutExpression();
try { try {
try { try {
return pointcutExpression.couldMatchJoinPointsInType(targetClass); return obtainPointcutExpression().couldMatchJoinPointsInType(targetClass);
} }
catch (ReflectionWorldException ex) { catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex); logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
@ -279,6 +283,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
} }
} }
} }
catch (IllegalArgumentException | IllegalStateException ex) {
throw ex;
}
catch (Throwable ex) { catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex); logger.debug("PointcutExpression matching rejected target class", ex);
} }
@ -287,7 +294,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override @Override
public boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions) { public boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions) {
obtainPointcutExpression();
ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass); ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass);
// Special handling for this, target, @this, @target, @annotation // Special handling for this, target, @this, @target, @annotation
@ -325,7 +331,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override @Override
public boolean matches(Method method, Class<?> targetClass, Object... args) { public boolean matches(Method method, Class<?> targetClass, Object... args) {
obtainPointcutExpression();
ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass); ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass);
// Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target, // Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target,

15
spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java

@ -23,8 +23,6 @@ import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import test.annotation.EmptySpringAnnotation; import test.annotation.EmptySpringAnnotation;
@ -41,7 +39,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.beans.testfixture.beans.subpkg.DeepBean; import org.springframework.beans.testfixture.beans.subpkg.DeepBean;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@ -174,7 +171,7 @@ class AspectJExpressionPointcutTests {
void testFriendlyErrorOnNoLocationClassMatching() { void testFriendlyErrorOnNoLocationClassMatching() {
AspectJExpressionPointcut pc = new AspectJExpressionPointcut(); AspectJExpressionPointcut pc = new AspectJExpressionPointcut();
assertThatIllegalStateException() assertThatIllegalStateException()
.isThrownBy(() -> pc.matches(ITestBean.class)) .isThrownBy(() -> pc.getClassFilter().matches(ITestBean.class))
.withMessageContaining("expression"); .withMessageContaining("expression");
} }
@ -182,7 +179,7 @@ class AspectJExpressionPointcutTests {
void testFriendlyErrorOnNoLocation2ArgMatching() { void testFriendlyErrorOnNoLocation2ArgMatching() {
AspectJExpressionPointcut pc = new AspectJExpressionPointcut(); AspectJExpressionPointcut pc = new AspectJExpressionPointcut();
assertThatIllegalStateException() assertThatIllegalStateException()
.isThrownBy(() -> pc.matches(getAge, ITestBean.class)) .isThrownBy(() -> pc.getMethodMatcher().matches(getAge, ITestBean.class))
.withMessageContaining("expression"); .withMessageContaining("expression");
} }
@ -190,7 +187,7 @@ class AspectJExpressionPointcutTests {
void testFriendlyErrorOnNoLocation3ArgMatching() { void testFriendlyErrorOnNoLocation3ArgMatching() {
AspectJExpressionPointcut pc = new AspectJExpressionPointcut(); AspectJExpressionPointcut pc = new AspectJExpressionPointcut();
assertThatIllegalStateException() assertThatIllegalStateException()
.isThrownBy(() -> pc.matches(getAge, ITestBean.class, (Object[]) null)) .isThrownBy(() -> pc.getMethodMatcher().matches(getAge, ITestBean.class, (Object[]) null))
.withMessageContaining("expression"); .withMessageContaining("expression");
} }
@ -246,7 +243,7 @@ class AspectJExpressionPointcutTests {
@Test @Test
void testInvalidExpression() { void testInvalidExpression() {
String expression = "execution(void org.springframework.beans.testfixture.beans.TestBean.setSomeNumber(Number) && args(Double)"; String expression = "execution(void org.springframework.beans.testfixture.beans.TestBean.setSomeNumber(Number) && args(Double)";
assertThatIllegalArgumentException().isThrownBy(getPointcut(expression)::getClassFilter); // call to getClassFilter forces resolution assertThatIllegalArgumentException().isThrownBy(() -> getPointcut(expression).getClassFilter().matches(Object.class));
} }
private TestBean getAdvisedProxy(String pointcutExpression, CallCountingInterceptor interceptor) { private TestBean getAdvisedProxy(String pointcutExpression, CallCountingInterceptor interceptor) {
@ -276,9 +273,7 @@ class AspectJExpressionPointcutTests {
@Test @Test
void testWithUnsupportedPointcutPrimitive() { void testWithUnsupportedPointcutPrimitive() {
String expression = "call(int org.springframework.beans.testfixture.beans.TestBean.getAge())"; String expression = "call(int org.springframework.beans.testfixture.beans.TestBean.getAge())";
assertThatExceptionOfType(UnsupportedPointcutPrimitiveException.class) assertThat(getPointcut(expression).getClassFilter().matches(Object.class)).isFalse();
.isThrownBy(() -> getPointcut(expression).getClassFilter()) // call to getClassFilter forces resolution...
.satisfies(ex -> assertThat(ex.getUnsupportedPrimitive()).isEqualTo(PointcutPrimitive.CALL));
} }
@Test @Test

Loading…
Cancel
Save