Skip to content

When use a @args as pointcut, there is case that occur a NPE at calling the unrelated method [SPR-13102] #17693

Closed
@spring-projects-issues

Description

@spring-projects-issues

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:

Backported to: 3.2.14

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions