Community
Participate
Working Groups
I got NullPointerException when . placing abstract aspcet(1) that has abstract pointcut and advice in jar file . overriding abstract pointcut using the joinpoint that has cflow in the aspect(2) here is the part of stack trace: [iajc] java.lang.NullPointerException [iajc] at org.aspectj.weaver.patterns.CflowPointcut.concretize1(CflowPointcut.java:126) [iajc] at org.aspectj.weaver.patterns.ReferencePointcut.concretize1(ReferencePointcut.java:270) [iajc] at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:127) [iajc] at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:120) [iajc] at org.aspectj.weaver.Advice.concretize(Advice.java:216) [iajc] at org.aspectj.weaver.CrosscuttingMembers.addShadowMunger(CrosscuttingMembers.java:78) [iajc] at org.aspectj.weaver.CrosscuttingMembers.addShadowMungers(CrosscuttingMembers.java:72) [iajc] at org.aspectj.weaver.ResolvedTypeX.collectCrosscuttingMembers(ResolvedTypeX.java:328) [iajc] at org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect(CrosscuttingMembersSet.java:50) [iajc] at org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration.buildInterTypeAndPerClause(AspectDeclaration.java:747) [iajc] at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.buildInterTypeAndPerClause(AjLookupEnvironment.java:120) [iajc] at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.completeTypeBindings(AjLookupEnvironment.java:87) [iajc] at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:310) [iajc] at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:324) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:372) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:133) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:78) [iajc] at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:106) [iajc] at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60) [iajc] at org.aspectj.tools.ajc.Main.run(Main.java:217) [iajc] at org.aspectj.tools.ajc.Main.runMain(Main.java:155) [iajc] at org.aspectj.tools.ant.taskdefs.AjcTask.executeInSameVM(AjcTask.java:990) [iajc] at org.aspectj.tools.ant.taskdefs.AjcTask.execute(AjcTask.java:863) [iajc] at org.apache.tools.ant.Task.perform(Task.java:341) [iajc] at org.apache.tools.ant.Target.execute(Target.java:309) [iajc] at org.apache.tools.ant.Target.performTasks(Target.java:336) [iajc] at org.apache.tools.ant.Project.executeTarget(Project.java:1339) [iajc] at org.apache.tools.ant.Project.executeTargets(Project.java:1255) [iajc] at org.apache.tools.ant.Main.runBuild(Main.java:609) [iajc] at org.apache.tools.ant.Main.start(Main.java:196) [iajc] at org.apache.tools.ant.Main.main(Main.java:235) [iajc] D:\dev\java\test\17ajNullPointerException\src\TestAspect.aj:0 Internal compiler error [iajc] java.lang.NullPointerException [iajc] at org.aspectj.weaver.patterns.CflowPointcut.concretize1(CflowPointcut.java:126) [iajc] at org.aspectj.weaver.patterns.ReferencePointcut.concretize1(ReferencePointcut.java:270) [iajc] at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:127) [iajc] at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:120) [iajc] at org.aspectj.weaver.Advice.concretize(Advice.java:216) [iajc] at org.aspectj.weaver.CrosscuttingMembers.addShadowMunger(CrosscuttingMembers.java:78) [iajc] at org.aspectj.weaver.CrosscuttingMembers.addShadowMungers(CrosscuttingMembers.java:72) [iajc] at org.aspectj.weaver.ResolvedTypeX.collectCrosscuttingMembers(ResolvedTypeX.java:328) [iajc] at org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect(CrosscuttingMembersSet.java:50) [iajc] at org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration.buildInterTypeAndPerClause(AspectDeclaration.java:747) [iajc] at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.buildInterTypeAndPerClause(AjLookupEnvironment.java:120) [iajc] at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.completeTypeBindings(AjLookupEnvironment.java:87) [iajc] at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:310) [iajc] at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:324) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:372) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:133) [iajc] at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:78) [iajc] at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:106) [iajc] at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60) [iajc] at org.aspectj.tools.ajc.Main.run(Main.java:217) [iajc] at org.aspectj.tools.ajc.Main.runMain(Main.java:155) [iajc] at org.aspectj.tools.ant.taskdefs.AjcTask.executeInSameVM(AjcTask.java:990) [iajc] at org.aspectj.tools.ant.taskdefs.AjcTask.execute(AjcTask.java:863) [iajc] at org.apache.tools.ant.Task.perform(Task.java:341) [iajc] at org.apache.tools.ant.Target.execute(Target.java:309) [iajc] at org.apache.tools.ant.Target.performTasks(Target.java:336) [iajc] at org.apache.tools.ant.Project.executeTarget(Project.java:1339) [iajc] at org.apache.tools.ant.Project.executeTargets(Project.java:1255) [iajc] at org.apache.tools.ant.Main.runBuild(Main.java:609) [iajc] at org.apache.tools.ant.Main.start(Main.java:196) [iajc] at org.apache.tools.ant.Main.main(Main.java:235) [iajc] !! no source information available !! [iajc] ABORT -- (1) AbstractAspect.aj -- public abstract aspect AbstractAspect{ public abstract pointcut directCall(); before(): directCall(){ System.out.println("direct"); } } -- TestAspect.aj -- public aspect TestAspect extends AbstractAspect{ public pointcut directCall(): execution(void Test.doSayHello(..)) && cflow(execution(void Test.direct(..))) ; } -- Test.java -- public class Test{ public static void main(String[] arguments){ Test test = new Test(); test.sayHello(); test.doSayHello(); } public void sayHello(){ doSayHello(); } public void doSayHello(){ System.out.println("hello."); } } -- build.xml -- <project name="whitedog" default="dist" basedir="."> <!-- set global properties for this build --> <property name="abstractaspect" value="abstractaspect" /> <property name="src" value="src" /> <property name="build" value="build" /> <property name="buildabstractaspect" value="buildabstractaspect" /> <property name="dist" value="dist" /> <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"> <!-- declare classes needed to run the tasks and tools --> <classpath> <pathelement location="aspectjtools.jar"/> </classpath> </taskdef> <target name="init"> <!-- Create the time stamp --> <tstamp /> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}" /> <mkdir dir="${buildabstractaspect}" /> <mkdir dir="${dist}" /> </target> <target name="compileabstractaspect" depends="init"> <iajc srcdir="abstractaspect" destDir="${buildabstractaspect}" classpath="aspectjrt.jar" /> </target> <target name="distabstractaspect" depends="compileabstractaspect"> <jar destfile="${dist}/abstractaspect.jar" basedir="${buildabstractaspect}" includes="*" /> </target> <target name="compile" depends="distabstractaspect"> <iajc srcdir="src" destDir="${build}" classpath="aspectjrt.jar" aspectPath="${dist}/abstractaspect.jar" /> </target> <target name="dist" depends="compile"> <jar destfile="${dist}/test.jar" basedir="${build}" includes="*" /> </target> <target name="clean"> <delete dir="${build}" /> <delete dir="${buildabstractaspect}" /> </target> </project> ---- When not placing aspect(1) in jar or not using cflow in the aspect(2), I didn't get NullPointerException. I want to get workarounds.
I'm redefining this as a P2 critical bug since you can work-around it by not using a .jar file for your library aspects but it is a major problem with that feature. The bug was easy to reproduce from your code below, and a test has been added to bugs/cflowAndJar and to ajcTestsFailing.xml. We will try to resolve this before the 1.1.1 release.
The NPE comes out because no-one has called resolveBindings() on the CflowPointcut - if they had then freeVars would have been initialized, and not be null when the concretize1() method is called (the source of the NPE). Below I'm documenting my findings so far, I don't have a fix yet and am floundering a bit - I'm not sure whether to add my comments here or on aspectj- dev... I traced back through the compilation process and nowhere could I find the top level call to resolve that would cause the various pointcut subtypes to be resolved. In our case I would expect to have seen at least a call to the AndPointcut.resolveBindings() as there are two halves to the pointcuts we are working with in this aspect. I can see that resolveBindings() is always called from Pointcut.resolve() - but again I couldn't see anywhere that drove that path through the code. The only resolving I could see was a call to resolvePerClause (marked XXX) at the end of AspectDeclaration.buildPerClause(). I could see a resolve() method in AspectDeclaration that would drive the appropriate codepath to call resolve() on my Pointcuts (and so correctly call CflowPointcut.resolveBindings()). Looking at a 'normal' compile that does not use a library like this, I see that org.eclipse.jdt.internal.compiler.Compiler.compile() drives AjCompiler.process for each 'unit' it knows about which leads to AspectDeclaration.resolve(). In the case of using a library, we never call AjCompiler.process() for some of the units (I believe its the ones in the jar?). Anyway, my first stab at a fix was simply to put a call to resolve() just before the call to resolvePerClause() in AspectDeclaration.buildPerClause (ClassScope scope) - That works (see below that I had to modify the testcase currently checked in). BUT it breaks all the normal tests. I think because for the tests that don't use libraries, we are resolving twice. ---- Changing the test XML --- Once the compile problem disappeared I hit the problem that the compiler said AbstractAspect was already woven. I had to change the XML line in the test definition from <compile files="lib.jar,Test.java,TestAspect.aj"/> to <compile files="Test.java,TestAspect.aj" aspectpath="lib.jar"/> And now it works.
tests and fix now in tree The issue was a subtle one having to do with the two phases of the compiler. The first ajdt phase is the extension of the eclipse compiler. This phase should never try to concretize advice; however, it does need to concretize other crosscutting declarations such as inter-type declarations. The problem was that reading in an aspect from the aspectpath produced some concrete advice duing the ajdt phase which wasn't prepared to handle it. I implemented the minimal fix for 1.1.1 of making sure that EclipseType will ignore all concrete advice -- this is postponed to the second weaving phase. I'll try and find time to write up a better description of these phases later.
updated target milestone field to 1.1.1