Closed
Description
Kazuki Shimizu opened SPR-13102 and commented
I used a @args
as PCD(Point Cut Designator), there is case that occur a NPE at calling the unrelated method.
if all of following cases are matched, NPE are occurs.
- A pointcut define using a
@args
. - Define a both with java method that applying AOP and java method that not applying AOP.
- Call a java method that not applying AOP with specifying a null parameter.
java.lang.NullPointerException
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.visit(ShadowMatchImpl.java:195)
at org.aspectj.weaver.ast.HasAnnotation.accept(HasAnnotation.java:31)
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.matches(ShadowMatchImpl.java:132)
at org.aspectj.weaver.reflect.ShadowMatchImpl.matchesJoinPoint(ShadowMatchImpl.java:87)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:167)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at org.springframework.issues.SampleService$$EnhancerBySpringCGLIB$$832f92bb.execute(<generated>)
at org.springframework.issues.ReproTests.executeWithNull(ReproTests.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
For example:
Target Class
public class SampleService {
/**
* Not matched method on {@link LoggingAspect}.
*/
public void execute(SampleInputBean inputBean) {
System.out.println(getClass().getName() + "#execute(SampleInputBean) called.");
}
/**
* Matched method on {@link LoggingAspect}
* <p>
* The SampleDto class have a {@link Loggable} annotation.
*/
public void execute(SampleDto dto) {
System.out.println(getClass().getName() + "#execute(SampleDto) called.");
}
}
Aspect
@Aspect
public class LoggingAspect {
@Before("@args(org.springframework.issues.Loggable))")
public void loggingBeginByAtArgs() {
System.out.println("★★★start by @args★★★★");
}
}
JavaBean(TDO)
@Loggable
public class SampleDto {
}
public class SampleInputBean {
}
Test Case
@Test
public void test() {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("org/springframework/issues/ReproTests-context.xml");
ctx.registerShutdownHook();
SampleService sampleService = ctx.getBean("sampleService", SampleService.class);
sampleService.execute(new SampleDto()); // -> OK
sampleService.execute(new SampleInputBean()); // -> OK
sampleService.execute((SampleDto)null); // -> OK
sampleService.execute((SampleInputBean)null); // -> NPE
}
Affects: 3.2.13, 4.1.6
Issue Links:
- Unsafe fallback pointcut construction in AspectJExpressionPointcut [SPR-9335] #13973 Unsafe fallback pointcut construction in AspectJExpressionPointcut
- Pointcut evaluation fails against AbstractHandlerMethodMapping$MappingRegistry with AspectJ 1.8.10 [SPR-15019] #19586 Pointcut evaluation fails against AbstractHandlerMethodMapping$MappingRegistry with AspectJ 1.8.10
Backported to: 3.2.14