Bug 39462 - Compiler crashes in jar and cflow
Summary: Compiler crashes in jar and cflow
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 2000
: P2 critical (vote)
Target Milestone: 1.1.1   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-06-30 00:44 EDT by NAKAGUCHI Takao CLA
Modified: 2003-08-28 08:06 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 NAKAGUCHI Takao CLA 2003-06-30 00:44:12 EDT
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.
Comment 1 Jim Hugunin CLA 2003-07-02 19:25:35 EDT
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.
Comment 2 Andrew Clement CLA 2003-07-22 13:17:39 EDT
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.
Comment 3 Jim Hugunin CLA 2003-07-22 19:16:09 EDT
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.
Comment 4 Adrian Colyer CLA 2003-08-28 08:06:05 EDT
updated target milestone field to 1.1.1