Bug 145018 - [ataspectj][matching] NPE weaving complex pointcuts with if()
Summary: [ataspectj][matching] NPE weaving complex pointcuts with if()
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-02 01:01 EDT by comron sattari CLA
Modified: 2013-06-24 11:04 EDT (History)
3 users (show)

See Also:


Attachments
Beginnings of a fix (2.56 KB, patch)
2008-03-20 12:09 EDT, Andrew Clement CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description comron sattari CLA 2006-06-02 01:01:42 EDT
I've run into a problem with @AspectJ. When I try to use if() in a pointcut like the following, I get a dump of the class it is advising and this exception.


     [iajc]  -- (NullPointerException) null
     [iajc] null
     [iajc] java.lang.NullPointerException
     [iajc]     at org.aspectj.weaver.ast.Test.makeInstanceof(Test.java:78)
     [iajc]     at org.aspectj.weaver.patterns.IfPointcut.findResidueInternal(IfPointcut.java:222)
     [iajc]     at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
     [iajc]     at org.aspectj.weaver.patterns.AndPointcut.findResidueInternal(AndPointcut.java:93)
     [iajc]     at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
     [iajc]     at org.aspectj.weaver.patterns.AndPointcut.findResidueInternal(AndPointcut.java:93)
     [iajc]     at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
     [iajc]     at org.aspectj.weaver.patterns.AndPointcut.findResidueInternal(AndPointcut.java:93)
     [iajc]     at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
     [iajc]     at org.aspectj.weaver.bcel.BcelAdvice.specializeOn(BcelAdvice.java:132)
     [iajc]     at org.aspectj.weaver.bcel.BcelShadow.prepareForMungers(BcelShadow.java:325)
     [iajc]     at org.aspectj.weaver.Shadow.implement(Shadow.java:455)
     [iajc]     at org.aspectj.weaver.bcel.BcelClassWeaver.implement(BcelClassWeaver.java:2236)
     [iajc]     at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:491)
     [iajc]     at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:109)
     [iajc]     at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1560)
     [iajc]     at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1511)
     [iajc]     at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1291)
     [iajc]     at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1113)
     [iajc]     at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:311)
     [iajc]     at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:183)
     [iajc]     at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$afterReturning$org_aspectj_ajdt_internal_compiler_CompilerAdapter$2$f9cc9ca0(CompilerAdapter.aj:70)
     [iajc]     at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:367)
     [iajc]     at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:862)
     [iajc]     at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:242)
     [iajc]     at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:161)
     [iajc]     at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:112)
     [iajc]     at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60)
     [iajc]     at org.aspectj.tools.ajc.Main.run(Main.java:367)
     [iajc]     at org.aspectj.tools.ajc.Main.runMain(Main.java:246)
     [iajc]     at org.aspectj.tools.ant.taskdefs.AjcTask.executeInSameVM(AjcTask.java:1262)
     [iajc]     at org.aspectj.tools.ant.taskdefs.AjcTask.execute(AjcTask.java:1056)
     [iajc]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
     [iajc]     at org.apache.tools.ant.Task.perform(Task.java:364)
     [iajc]     at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:64)
     [iajc]     at net.sf.antcontrib.logic.IfTask.execute(IfTask.java:197)
     [iajc]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     [iajc]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     [iajc]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     [iajc]     at java.lang.reflect.Method.invoke(Method.java:585)
     [iajc]     at org.apache.tools.ant.TaskAdapter.execute(TaskAdapter.java:123)
     [iajc]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
     [iajc]     at org.apache.tools.ant.Task.perform(Task.java:364)
     [iajc]     at org.apache.tools.ant.Target.execute(Target.java:341)
     [iajc]     at org.apache.tools.ant.Target.performTasks(Target.java:369)
     [iajc]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1216)
     [iajc]     at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:37)
     [iajc]     at org.apache.tools.ant.Project.executeTargets(Project.java:1068)
     [iajc]     at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:382)
     [iajc]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
     [iajc]     at org.apache.tools.ant.Task.perform(Task.java:364)
     [iajc]     at org.apache.tools.ant.Target.execute(Target.java:341)
     [iajc]     at org.apache.tools.ant.Target.performTasks(Target.java:369)
     [iajc]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1216)
     [iajc]     at org.apache.tools.ant.Project.executeTarget(Project.java:1185)
     [iajc]     at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:40)
     [iajc]     at org.apache.tools.ant.Project.executeTargets(Project.java:1068)
     [iajc]     at org.apache.tools.ant.Main.runBuild(Main.java:668)
     [iajc]     at org.apache.tools.ant.Main.startAnt(Main.java:187)
     [iajc]     at org.apache.tools.ant.launch.Launcher.run(Launcher.java:246)
     [iajc]     at org.apache.tools.ant.launch.Launcher.main(Launcher.java:67) 

If I however get rid of the args() in the cflow() it works, is this expected?  The second example (the one that causes the problem) works as I would expect it to without the if(), it correctly exposes the context from both pointcuts.


	THIS WORKS
    @Pointcut("call( * *.someMethod(..)) && args(arg1, arg2, arg3, status) ")
    public void someMethod2( int arg1, int arg2, int arg3, Status status ) {}

    @Pointcut("someMethod2(arg1, arg2, arg3, status) && if()")
    public static boolean someMethod2if(int arg1, int arg2, int arg3, Status status) {
        return status.equals( Status.DELETED );
    }

    @Pointcut("cflow(execution( * *.doProcess(..) ) ) && this(com.ec.SomeClass+) ")
    public void inSomeClass2() {}

    @After( "inSomeClass2() && someMethod2if(arg1, arg2, arg3, status) ")
    public void deleteManagerInSomeClass2( int arg1, int arg2, int arg3, Status status) {
             _log.write( DEBUG, "STATUS: " + status );

    }


	THIS DOES NOT
    @Pointcut("call( * *.someMethod(..)) && args(arg1, arg2, arg3, status) ")
    public void someMethod2( int arg1, int arg2, int arg3, Status status ) {}

    @Pointcut("someMethod2(arg1, arg2, arg3, status) && if()")
    public static boolean someMethod2if(int arg1, int arg2, int arg3, Status status) {
        return status.equals( Status.DELETED );
    }

    @Pointcut("cflow(execution( * *.doProcess(..) ) && args( context, *, args )) && this(com.ec.SomeClass+) ")
    public void inSomeClass2(Context context, Map args) {}

    @After( "inSomeClass2(context,args) && someMethod2if(arg1, arg2, arg3, status) ")
    public void deleteManagerInSomeClass2( Context context, Map args, int arg1, int arg2, int arg3, Status status) {
             _log.write( DEBUG, "STATUS2: " + status );

    }
Comment 1 comron sattari CLA 2006-06-02 01:03:08 EDT
Sorry for the poor formatting.
Comment 2 Andrew Clement CLA 2006-06-02 03:54:16 EDT
testcase added (commented out in Ajc152Tests) - does this all work fine with code style rather than annotation style?
Comment 3 comron sattari CLA 2006-06-02 04:42:39 EDT
I have not tried code style. I can test it out, but don't have the time to do so right now.
Comment 4 Andrew Clement CLA 2008-03-17 20:06:15 EDT
It still fails at 160 too.  To avoid the NPE I tweaked the Pointcut Rewriter - this was not correctly ensuring the ConcreteCflowPointcut was occurring before the If pointcut when final concretization was occurring - this left an element of the exposed state at the joinpoint null and so the NPE.  Switching them around causes the Cflow pointcut to correctly insert its entry - but then we fail later because we can't convert from a Map to an int.  Here is the simplified code that fails in the same way:

    @Pointcut("call(* someMethod(..)) && args(arg1) && if()")
    public static boolean someMethod2if(int arg1) {
      return true;
    }

    @Pointcut("cflow(execution(* doProcess(..) ) && args(*, args)) && this(SomeClass+) ")
    public void inSomeClass2(Map args) {}

    @After( "inSomeClass2(args) && someMethod2if(arg1) ")
    public void deleteManagerInSomeClass2(Map args,int arg1) { }
    

This reason we try is that someMethod2If() takes an int (and is at index 0) - whilst at the shadow the parameters are (map,int).  In code style we do the right thing, but for some reason in Annotation Style we ignore the useful information we have collected that maps required method parameters to exposed state.  Changing it to use this information causes this test to pass but some others to fail in the suite.
Comment 5 Andrew Clement CLA 2008-03-20 12:09:48 EDT
Created attachment 93036 [details]
Beginnings of a fix

Beginnings of a fix for this.  It fixes this failing case but another couple of the tests in the suite fail, needs more thought before being complete.
Comment 6 Andrew Clement CLA 2013-06-24 11:04:31 EDT
unsetting the target field which is currently set for something already released