Skip to content
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

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 opened this issue Jun 7, 2015 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jun 7, 2015

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

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I submit a pull-request in reporting project.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Andy Clement, this turns out to be an issue in AspectJ's RuntimeTestEvaluator.visit(HasAnnotation) implementation where the code isn't able to deal with a null value. I'm addressing this in Spring Framework 4.1.7 though a defensive catch block around our ShadowMatch.matchesJoinPoint call in Spring's AspectJExpressionPointcut but I suppose that's worth fixing in AspectJ itself as well.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I'll backport this not only to 4.1.7 but to 3.2.14 as well, since it doesn't seem to hurt to be defensive there.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants