Bug 118149 - AspectJ compiler crahses possibly due to poincut context binding issue
Summary: AspectJ compiler crahses possibly due to poincut context binding issue
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: 1.5.0RC1   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-27 01:01 EST by Ramnivas Laddad CLA
Modified: 2012-04-03 14:24 EDT (History)
0 users

See Also:


Attachments
testcase patch (3.72 KB, patch)
2005-12-05 04:45 EST, Helen Beeken CLA
no flags Details | Diff
simplified testcase (2.22 KB, patch)
2005-12-05 10:08 EST, Helen Beeken CLA
aclement: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ramnivas Laddad CLA 2005-11-27 01:01:55 EST
I am using the latest version of AJDT (1.3.0.20051125115230).


The reason is not entirely clear, but I have a pointcut of form 
    public pointcut realPC(Common entity)
    	: pc1(entity) || pc2(entity);

Just a few hours back, I used to get an error regarding incompatible binding
of entity in the || poincut. When I got that error, Eclipse was frozen to the 
point that clicking "Details" on exception report made Eclipse hang and 
had to kill it using the task manager. So I modified the program to avoid
|| expression in pointcut, after unsuccessfully trying various ways to 
express the pointcut. It was an ugly thing to do, since I essentially had to 
duplicate the advice for both pointcuts. Anyway...

Then I tried to reproduce on a smaller project to provide a minimal
program to reproduced the bug. However, it worked just fine on that project
(and I couldn't see any material difference in the pointcuts or the classes
involved). Encouraged by this, I retried the or-ed version of the pointcut
on the real project. This time, I get the crash and can acccess the stack
trace.

java.lang.NullPointerException
at org.aspectj.weaver.ast.Test.makeInstanceof(Test.java:78)
at org.aspectj.weaver.patterns.IfPointcut.findResidueInternal(IfPointcut.java:181)
at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
at org.aspectj.weaver.patterns.AndPointcut.findResidueInternal(AndPointcut.java:97)
at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
at org.aspectj.weaver.patterns.AndPointcut.findResidueInternal(AndPointcut.java:97)
at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
at org.aspectj.weaver.patterns.OrPointcut.findResidueInternal(OrPointcut.java:99)
at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
at org.aspectj.weaver.patterns.OrPointcut.findResidueInternal(OrPointcut.java:99)
at org.aspectj.weaver.patterns.Pointcut.findResidue(Pointcut.java:267)
at org.aspectj.weaver.bcel.BcelAdvice.specializeOn(BcelAdvice.java:133)
at org.aspectj.weaver.bcel.BcelShadow.prepareForMungers(BcelShadow.java:308)
at org.aspectj.weaver.Shadow.implement(Shadow.java:404)
at org.aspectj.weaver.bcel.BcelClassWeaver.implement(BcelClassWeaver.java:2146)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:467)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:102)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1534)
at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1485)
at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1266)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1088)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:300)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:178)
at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$afterReturning$org_aspectj_ajdt_internal_compiler_CompilerAdapter$2$f9cc9ca0(CompilerAdapter.aj:70)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:367)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:809)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:230)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:156)
at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:122)
at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)

trouble in: 
public abstract class com.aspectivity.mgmt.web.entity.ManageEntity extends com.aspectivity.mgmt.web.TemplatePage:
  public void <init>(com.aspectivity.mgmt.model.Entity, boolean, String, String, String, String, String)    org.aspectj.weaver.MethodDeclarationLineNumber: 19:557
:
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 19)
                    INVOKESPECIAL com.aspectivity.mgmt.web.TemplatePage.<init> ()V
                    ALOAD_1
                    ASTORE 9
                    ILOAD_2
                    ISTORE 10
                    ALOAD_3
                    ASTORE 11
                    ALOAD 4
                    ASTORE 12
                    ALOAD 5
                    ASTORE 13
                    ALOAD 6
                    ASTORE 14
                    ALOAD 7
                    ASTORE 15
    constructor-execution(void com.aspectivity.mgmt.web.entity.ManageEntity.<init>(com.aspectivity.mgmt.model.Entity, boolean, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String))
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 23)
    |               ALOAD_3     // java.lang.String pageTitle
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.setPageTitle (Ljava/lang/String;)V
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 25)
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
    |               ALOAD_1     // com.aspectivity.mgmt.model.Entity entity
    |               ALOAD 5     // java.lang.String addEntityLinkText
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.getEntitiesListView (Lcom/aspectivity/mgmt/model/Entity;Ljava/lang/String;)Lwicket/markup/html/list/ListView;
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 27)
    |               LDC "addEntityLink"
    |               ACONST_NULL
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.getEditLink (Ljava/lang/String;Lcom/aspectivity/mgmt/model/Entity;)Lwicket/markup/html/link/Link;
    |               ASTORE 8
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 28)
    |               ALOAD 8     // wicket.markup.html.link.Link addEntityLink
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |               ALOAD 8     // wicket.markup.html.link.Link addEntityLink   (line 29)
    |               NEW wicket.markup.html.basic.Label
    |               DUP
    |               LDC "addEntityLinkText"
    |               ALOAD 5     // java.lang.String addEntityLinkText
    |               INVOKESPECIAL wicket.markup.html.basic.Label.<init> (Ljava/lang/String;Ljava/lang/String;)V
    |               INVOKEVIRTUAL wicket.markup.html.link.Link.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |               ILOAD_2     // boolean isInitialView   (line 31)
    |               IFEQ L0
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 32)
    |               NEW wicket.markup.html.basic.Label
    |               DUP
    |               LDC "editEntity"
    |               LDC ""
    |               INVOKESPECIAL wicket.markup.html.basic.Label.<init> (Ljava/lang/String;Ljava/lang/String;)V
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |               GOTO L1
    |           L0: ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 34)
    |               ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
    |               ALOAD_1     // com.aspectivity.mgmt.model.Entity entity
    |               ILOAD_2     // boolean isInitialView
    |               ALOAD 6     // java.lang.String addPanelTtile
    |               ALOAD 7     // java.lang.String editPanelTitle
    |               INVOKESPECIAL com.aspectivity.mgmt.web.entity.ManageEntity.getEditPanel (Lcom/aspectivity/mgmt/model/Entity;ZLjava/lang/String;Ljava/lang/String;)Lwicket/Component;
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |           L1: ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 37)
    |               NEW wicket.markup.html.basic.Label
    |               DUP
    |               LDC "listViewTitle"
    |               ALOAD 4     // java.lang.String listViewTitle
    |               INVOKESPECIAL wicket.markup.html.basic.Label.<init> (Ljava/lang/String;Ljava/lang/String;)V
    |               INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.add (Lwicket/Component;)Lwicket/MarkupContainer;
    |               POP
    |               RETURN   (line 38)
    constructor-execution(void com.aspectivity.mgmt.web.entity.ManageEntity.<init>(com.aspectivity.mgmt.model.Entity, boolean, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String))
  end public void <init>(com.aspectivity.mgmt.model.Entity, boolean, String, String, String, String, String)

  protected abstract com.aspectivity.mgmt.model.Entity createNewEntity()    org.aspectj.weaver.MethodDeclarationLineNumber: 40:1233
;

  protected abstract void removeEntity(com.aspectivity.mgmt.model.Entity)    org.aspectj.weaver.MethodDeclarationLineNumber: 41:1278
;

  protected abstract java.util.List getAllEntities()    org.aspectj.weaver.MethodDeclarationLineNumber: 42:1351
;

  protected abstract com.aspectivity.mgmt.web.entity.ManageEntity createNewPage(com.aspectivity.mgmt.model.Entity, boolean)    org.aspectj.weaver.MethodDeclarationLineNumber: 44:1406
;

  protected abstract wicket.Component createEditPanel(String, String, com.aspectivity.mgmt.model.Entity)    org.aspectj.weaver.MethodDeclarationLineNumber: 45:1490
;

  protected wicket.markup.html.list.ListView getEntitiesListView(com.aspectivity.mgmt.model.Entity, String)    org.aspectj.weaver.MethodDeclarationLineNumber: 47:1581
:
                    NEW com.aspectivity.mgmt.web.entity.EntityListView   (line 48)
                    DUP
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
                    LDC "entityList"
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
                    INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.getAllEntities ()Ljava/util/List;
                    ALOAD_1     // com.aspectivity.mgmt.model.Entity entity
                    INVOKESPECIAL com.aspectivity.mgmt.web.entity.EntityListView.<init> (Lcom/aspectivity/mgmt/web/entity/ManageEntity;Ljava/lang/String;Ljava/util/List;Lcom/aspectivity/mgmt/model/Entity;)V
                    ARETURN
  end protected wicket.markup.html.list.ListView getEntitiesListView(com.aspectivity.mgmt.model.Entity, String)

  protected wicket.markup.html.link.Link getEditLink(String, com.aspectivity.mgmt.model.Entity)    org.aspectj.weaver.MethodDeclarationLineNumber: 51:1743
:
                    NEW wicket.markup.html.link.PageLink   (line 52)
                    DUP
                    ALOAD_1     // java.lang.String name
                    NEW com.aspectivity.mgmt.web.entity.ManageEntity$1
                    DUP
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
                    ALOAD_2     // com.aspectivity.mgmt.model.Entity entity
                    INVOKESPECIAL com.aspectivity.mgmt.web.entity.ManageEntity$1.<init> (Lcom/aspectivity/mgmt/web/entity/ManageEntity;Lcom/aspectivity/mgmt/model/Entity;)V
                    INVOKESPECIAL wicket.markup.html.link.PageLink.<init> (Ljava/lang/String;Lwicket/markup/html/link/IPageLink;)V
                    ARETURN
  end protected wicket.markup.html.link.Link getEditLink(String, com.aspectivity.mgmt.model.Entity)

  protected wicket.markup.html.link.Link getRemoveLink(String, wicket.markup.html.list.ListItem)    org.aspectj.weaver.MethodDeclarationLineNumber: 63:2013
:
                    NEW com.aspectivity.mgmt.web.entity.ManageEntity$2   (line 64)
                    DUP
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this
                    ALOAD_1     // java.lang.String id
                    ALOAD_2     // wicket.markup.html.list.ListItem item
                    INVOKESPECIAL com.aspectivity.mgmt.web.entity.ManageEntity$2.<init> (Lcom/aspectivity/mgmt/web/entity/ManageEntity;Ljava/lang/String;Lwicket/markup/html/list/ListItem;)V
                    ARETURN
  end protected wicket.markup.html.link.Link getRemoveLink(String, wicket.markup.html.list.ListItem)

  private wicket.Component getEditPanel(com.aspectivity.mgmt.model.Entity, boolean, String, String)    org.aspectj.weaver.MethodDeclarationLineNumber: 75:2376
:
                    ALOAD_1     // com.aspectivity.mgmt.model.Entity entity   (line 77)
                    IFNONNULL L0
                    ALOAD_3     // java.lang.String addPanelTtile
                    GOTO L1
                L0: ALOAD 4     // java.lang.String editPanelTitle
                L1: ASTORE 5
                    ALOAD_1     // com.aspectivity.mgmt.model.Entity entity   (line 78)
                    IFNONNULL L2
                    ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 79)
                    INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.createNewEntity ()Lcom/aspectivity/mgmt/model/Entity;
                    ASTORE_1     // com.aspectivity.mgmt.model.Entity entity
                L2: ALOAD_0     // com.aspectivity.mgmt.web.entity.ManageEntity this   (line 81)
                    LDC "editEntity"
                    ALOAD 5     // java.lang.String panelTitle
                    ALOAD_1     // com.aspectivity.mgmt.model.Entity entity
                    INVOKEVIRTUAL com.aspectivity.mgmt.web.entity.ManageEntity.createEditPanel (Ljava/lang/String;Ljava/lang/String;Lcom/aspectivity/mgmt/model/Entity;)Lwicket/Component;
                    ARETURN
  end private wicket.Component getEditPanel(com.aspectivity.mgmt.model.Entity, boolean, String, String)

end public abstract class com.aspectivity.mgmt.web.entity.ManageEntity

when implementing on shadow constructor-execution(void com.aspectivity.mgmt.web.entity.ManageEntity.<init>(com.aspectivity.mgmt.model.Entity, boolean, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String))
when weaving type com.aspectivity.mgmt.web.entity.ManageEntity
when weaving classes 
when weaving 
when batch building BuildConfig[C:\work\projects\workspace\.metadata\.plugins\org.eclipse.ajdt.core\Aspectivity.generated.lst] #Files=87
Comment 1 Andrew Clement CLA 2005-12-02 06:25:27 EST
Ramnivas, to investigate this further we need to know the complete pointcuts you are using,  what are the definitions of pc1() and pc2() (and any other required pointcuts)?

We know the shadow that is causing the problem:

constructor-execution(void
com.aspectivity.mgmt.web.entity.ManageEntity.<init>(com.aspectivity.mgmt.model.Entity,
boolean, java.lang.String, java.lang.String, java.lang.String,
java.lang.String, java.lang.String))

so that + the pointcuts should be enough to progress.
Comment 2 Ramnivas Laddad CLA 2005-12-02 11:25:59 EST
Andy,

Here is the pointcut along with relevant parts of base and derived aspect.
public abstract aspect AbstractEntityManagementAspect {
    public abstract pointcut entityAccessor(CommonEntity entity);

    ... advice to the pointcut...
}

public aspect UIDEntityManagementAspect extends AbstractEntityManagementAspect {
    public pointcut entityAccessor1(CommonEntity entity)
        : (execution(* CommonEntity+.add*(CommonEntity+))
           || (execution(* CommonEntity+.remove*(CommonEntity+))))
          && within(CommonEntity+)
          && args(entity) && if(entity != null);
   
    public pointcut entityAccessor2(CommonEntity entity)
        : execution(ManageEntity.new(CommonEntity+, ..)) 
          && within(ManageEntity)
          && args(entity, ..) 
          && if(entity != null);
    
    public pointcut entityAccessor(CommonEntity entity)
        : entityAccessor1(entity) || entityAccessor2(entity);

    declare parents: Entity implements CommonEntity;
}
Comment 3 Helen Beeken CLA 2005-12-05 04:45:39 EST
Created attachment 31107 [details]
testcase patch

Apply the patch to the tests project.

With the given information in the previous comment I've recreated the problem and created an AJ testcase.

Note everything compiles fine (no NPE) if

public pointcut entityAccessor2(CommonEntity entity)
    : execution(ManageEntity.new(CommonEntity+, ..)) 
      && within(ManageEntity)
      && args(entity, ..)                          <-------------
      && if(entity != null);

is changed to:

public pointcut entityAccessor2(CommonEntity entity)
    : execution(ManageEntity.new(CommonEntity+, ..)) 
      && within(ManageEntity)
      && args(entity)                               <--------------
      && if(entity != null);
Comment 4 Helen Beeken CLA 2005-12-05 09:52:04 EST
Another note...it also doesn't fail (no NPE) if the two if pointcuts are removed ie. if we have:

    public pointcut entityAccessor1(CommonEntity entity)
        : (execution(* CommonEntity+.add*(CommonEntity+))
           || (execution(* CommonEntity+.remove*(CommonEntity+))))
          && within(CommonEntity+)
          && args(entity);

    public pointcut entityAccessor2(CommonEntity entity)
        : execution(ManageEntity.new(CommonEntity+, ..)) 
          && within(ManageEntity)
          && args(entity, ..) ;

    public pointcut entityAccessor(CommonEntity entity)
        : entityAccessor1(entity) || entityAccessor2(entity);

    declare parents: Entity implements CommonEntity;

Then the tests pass.
Comment 5 Helen Beeken CLA 2005-12-05 10:08:01 EST
Created attachment 31118 [details]
simplified testcase

Apply patch to the tests project.

This patch contains a simplified testcase to the one previously attached. It contains the three things needed to recreate this bug:

* An OR pointcut
* if pointcut
* args(something,..)
Comment 6 Adrian Colyer CLA 2005-12-05 22:20:53 EST
Thanks for the test case - that helped a lot. I've followed the code paths through, and found the cause of the bug. At the join point for the constructor taking (String, boolean), the side of the pointcut that matches using args(String) can never match, and so does not bind any variable. The other side of the pointcut does of course match in this case. Because there is no binding in that branch (legitimately) the Var can be null when we come to look at it. After much careful investigation, the fix is a simple one-line change to IfPointcut.findResidue to cope with this case.

Fix committed in tree, waiting on build.
Comment 7 Andrew Clement CLA 2005-12-07 06:40:13 EST
fix available.