Bug 62458 - An if() pointcut inside a perthis() clause causes an ABORT - null pointer exception in ajc
Summary: An if() pointcut inside a perthis() clause causes an ABORT - null pointer exc...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-05-17 07:21 EDT by Laurie Hendren CLA
Modified: 2005-08-17 14:55 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Laurie Hendren CLA 2004-05-17 07:21:42 EDT
An if() pointcut inside a perthis() causes the following dump:

ABORT

Exception thrown from AspectJ 1.2rc2

This might be logged as a bug already -- find current bugs at
  http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler

Bugs for exceptions thrown have titles File:line from the top stack, 
e.g., "SomeFile.java:243"

If you don't find the exception below in a bug, please add a new bug
at http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ
To make the bug a priority, please include a test program
that can reproduce this exception.
null
java.lang.NullPointerException
        at org.aspectj.weaver.patterns.IfPointcut.concretize1(IfPointcut.java:171)
        at org.aspectj.weaver.patterns.IfPointcut.concretize(IfPointcut.java:143)
        at org.aspectj.weaver.patterns.AndPointcut.concretize1(AndPointcut.java:88)
        at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:135)
        at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:122)
        at org.aspectj.weaver.patterns.PerObject.concretize(PerObject.java:84)
        at
org.aspectj.weaver.CrosscuttingMembers.setPerClause(CrosscuttingMembers.java:207)
        at
org.aspectj.weaver.ResolvedTypeX.collectCrosscuttingMembers(ResolvedTypeX.java:329)
        at
org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect(CrosscuttingMembersSet.java:57)
        at org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave(BcelWeaver.java:322)
        at
org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:222)
        at
org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:114)
        at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:376)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:601)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:160)
        at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:94)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:102)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:53)
        at org.aspectj.tools.ajc.Main.run(Main.java:280)
        at org.aspectj.tools.ajc.Main.runMain(Main.java:217)
        at org.aspectj.tools.ajc.Main.main(Main.java:79)


Here is a small test program to demonstrate the bug.  Just try compiling it.

public class Main {

  public static void main(String [] args) {
    System.out.println("Hello World");
  }

}

// Note the use of an if inside a perthis, causes the ajc compiler to
//    throw an exception
aspect Aspect perthis(call (* *(..))
// if you comment out the following line, everything is ok,  so
//   it seems tobe the use of if in the perthis that is not handled correctly 
                       && if(4==3)
                     )
{ before () : call(* *..*(..)) && !within(Aspect*)
  { System.out.println("Advice 1");
  }

}
Comment 1 Andrew Clement CLA 2004-05-17 09:23:43 EDT
I'm still working on this one, but if you put the if() into a pointcut 
definition, this will fix the problem:

aspect A perthis(definedPC()) {

  pointcut definedPC(): call(* *(..)) && if(4==3);
...

It is to do with the 'scope' within which we are attempting to concretize the if
().  The code seems to cope with two cases:
1) The if() is directly specified against advice.
2) The if() is in a declared pointcut definition.

This is a third case where there is no surrounding advice or pointcut def.
Comment 2 Andrew Clement CLA 2004-05-17 12:27:05 EDT
I managed to put a fix in that meant we did not blow up at compile time.  

Unfortunately this then led to a situation where we crash at runtime.  It 
turns out that we generate the implementation of the if_0() method (which 
contains the test you supplied in your if() PCD) when we do a postParse of the 
PointcutDeclaration (Driven through CompilationUnitScope.buildFieldsAndMethods
()).  If the if() test is inlined in the per clause, we don't postparse the 
pointcut and never generate the if_0() method.



Comment 3 Andrew Clement CLA 2004-05-18 12:08:15 EDT
Ensuring the if() test method is generated requires a significant change that 
I don't want to make between an RC and a final release of 1.2.  So, to prevent 
the compilation failing with an NPE I have added a compilation check to see if 
you are using if() in a per clause.  If you are, you will see:

"if() pointcut designator cannot be used directly in a per clause (compiler 
limitation).  Create a named pointcut containing the if() and refer to it"

I've added tests for all the various per clause types.

I will then make this bug an enhancement request for post 1.2
Comment 4 Adrian Colyer CLA 2005-08-17 14:55:00 EDT
The limitation that was the final resolution to this bug is not severe and easily worked around. No 
immediate plans to do anything further to alleviate this restriction. I'm marking as "FIXED" since that best 
describes the status of the main issue addressed by the bug report.