Bug 123695 - Internal nullptr exception with complex declare annotation statement that affects injected methods
Summary: Internal nullptr exception with complex declare annotation statement that aff...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.0RC2   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 1.5.1   Edit
Assignee: Andrew Clement CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-12 19:59 EST by Jean-Sébastien Légaré CLA
Modified: 2006-01-17 11:53 EST (History)
0 users

See Also:


Attachments
Contains 8 files (2 aspects, 4 annotations, 1 interface, 1 class) in one package (default package). Smallest application I could create that exhibits the bug. Everything is weaved on class Main. (2.73 KB, application/zip)
2006-01-12 20:03 EST, Jean-Sébastien Légaré CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-Sébastien Légaré CLA 2006-01-12 19:59:45 EST
I have an aspect that declares an annotation on a method based on a complex condition :

declare @method : !@(Write || Read) public !static * (@MarkMyMethods *).*(..) : @Write;

Basically that means that every type that is annotated with @MarkMyMethods should have all of its public non static methods be annotated with either @Read or @Write. If neither of @Read nor @Write is present on such a method, @Write is added by default.

I have another aspect that makes every type annotated with @InjectName implement  the Named interface :

public Interface Named { public String getName(); }

public aspect NameAspect {
  declare parents: @InjectName * implements Named;
  
  private String Named.name;	
  public  String Named.getName() { return name; }
}

As soon as I annotate a class with both @MarkMyMethods and @InjectName, I get an internal null pointer exception at weave time.

However if I change the first aspect to say :

  declare @method : !@(Read) public !static * (@MarkMyMethods *).*(..) : @Write;
  or
  declare @method : !@(Write) public !static * (@MarkMyMethods *).*(..) : @Write;

instead of the !@(Read || Write) one, everything compiles fine.

Here is a link to a small application that exhibits the bug. :
  
http://www.cs.mcgill.ca/~jlegar/src_jslegare.zip

==========
Here is the error output :

java.lang.NullPointerException
at org.aspectj.weaver.patterns.WildAnnotationTypePattern.matches(WildAnnotationTypePattern.java:61)
at org.aspectj.weaver.patterns.NotAnnotationTypePattern.matches(NotAnnotationTypePattern.java:35)
at org.aspectj.weaver.patterns.SignaturePattern.matchesAnnotations(SignaturePattern.java:488)
at org.aspectj.weaver.patterns.SignaturePattern.matchesExactly(SignaturePattern.java:331)
at org.aspectj.weaver.patterns.SignaturePattern.matches(SignaturePattern.java:288)
at org.aspectj.weaver.patterns.DeclareAnnotation.matches(DeclareAnnotation.java:247)
at org.aspectj.weaver.bcel.BcelClassWeaver.weaveAtMethodOnITDSRepeatedly(BcelClassWeaver.java:995)
at org.aspectj.weaver.bcel.BcelClassWeaver.weaveDeclareAtMethodCtor(BcelClassWeaver.java:730)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:430)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:102)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1543)
at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1494)
at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1275)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1078)
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:811)
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 class NameAspect extends java.lang.Object:
  TypeMungers: [(BcelTypeMunger ResolvedTypeMunger(Method, java.lang.String Named.getName())), (BcelTypeMunger ResolvedTypeMunger(Field, java.lang.String Named.name))]
     declares: [declare parents: @InjectName * extends (Named);]
  private static Throwable ajc$initFailureCause
  public static final NameAspect ajc$perSingletonInstance
  static void <clinit>():
    catch java.lang.Throwable -> E0
    |               INVOKESTATIC NameAspect.ajc$postClinit ()V   (line 2)
    catch java.lang.Throwable -> E0
                    GOTO L0
                E0: ASTORE_0
                    ALOAD_0
                    PUTSTATIC NameAspect.ajc$initFailureCause Ljava/lang/Throwable;
                L0: RETURN
  end static void <clinit>()

  public void <init>():
                    ALOAD_0     // NameAspect this   (line 2)
                    INVOKESPECIAL java.lang.Object.<init> ()V
                    RETURN
  end public void <init>()

  void ajc$declare_parents_1()    org.aspectj.weaver.MethodDeclarationLineNumber: 5:40
:
                    RETURN   (line 5)
  end void ajc$declare_parents_1()

  public static String ajc$interMethod$NameAspect$Named$getName(Named)    EffectiveSignatureAttribute(java.lang.String Named.getName(), method-execution)
:
                    ALOAD_0     // Named ajc$this_   (line 11)
                    INVOKESTATIC NameAspect.ajc$interFieldGetDispatch$NameAspect$Named$name (LNamed;)Ljava/lang/String;
                    ARETURN
  end public static String ajc$interMethod$NameAspect$Named$getName(Named)

  public static String ajc$interMethodDispatch1$NameAspect$Named$getName(Named)    EffectiveSignatureAttribute(java.lang.String Named.getName(), method-call)
:
                    ALOAD_0
                    INVOKEINTERFACE Named.getName ()Ljava/lang/String;
                    ARETURN
  end public static String ajc$interMethodDispatch1$NameAspect$Named$getName(Named)

  public static void ajc$interFieldInit$NameAspect$Named$name(Named)    org.aspectj.weaver.MethodDeclarationLineNumber: 12:279
:
                    RETURN   (line 12)
  end public static void ajc$interFieldInit$NameAspect$Named$name(Named)

  public static String ajc$interFieldGetDispatch$NameAspect$Named$name(Named)    EffectiveSignatureAttribute(java.lang.String Named.name, field-get)
:
                    ALOAD_0
                    INVOKEINTERFACE Named.ajc$interFieldGet$NameAspect$Named$name ()Ljava/lang/String;
                    ARETURN
  end public static String ajc$interFieldGetDispatch$NameAspect$Named$name(Named)

  public static void ajc$interFieldSetDispatch$NameAspect$Named$name(Named, String)    EffectiveSignatureAttribute(java.lang.String Named.name, field-set)
:
                    ALOAD_0
                    ALOAD_1
                    INVOKEINTERFACE Named.ajc$interFieldSet$NameAspect$Named$name (Ljava/lang/String;)V
                    RETURN
  end public static void ajc$interFieldSetDispatch$NameAspect$Named$name(Named, String)

  public void ajc$after$NameAspect$1$dd96786a(Named)    AdviceAttribute(after, (execution(Named+.new(..)) && target(BindingTypePattern(Named, 0))), 0, 296)
:
                    GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 15)
                    LDC "A new name was created"
                    INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
                    ALOAD_1     // Named newinstance   (line 16)
                    LDC "TikaTikaSlimShady"
                    INVOKESTATIC NameAspect.ajc$interFieldSetDispatch$NameAspect$Named$name (LNamed;Ljava/lang/String;)V
                    RETURN   (line 17)
  end public void ajc$after$NameAspect$1$dd96786a(Named)

  public static NameAspect aspectOf()    org.aspectj.weaver.AjAttribute$AjSynthetic@14d92f0
:
                    GETSTATIC NameAspect.ajc$perSingletonInstance LNameAspect;
                    IFNONNULL L0
                    NEW org.aspectj.lang.NoAspectBoundException
                    DUP
                    LDC "NameAspect"
                    GETSTATIC NameAspect.ajc$initFailureCause Ljava/lang/Throwable;
                    INVOKESPECIAL org.aspectj.lang.NoAspectBoundException.<init> (Ljava/lang/String;Ljava/lang/Throwable;)V
                    ATHROW
                L0: GETSTATIC NameAspect.ajc$perSingletonInstance LNameAspect;
                    ARETURN
  end public static NameAspect aspectOf()

  public static boolean hasAspect()    org.aspectj.weaver.AjAttribute$AjSynthetic@12e2f2e
:
                    GETSTATIC NameAspect.ajc$perSingletonInstance LNameAspect;
                    IFNULL L0
                    ICONST_1
                    IRETURN
                L0: ICONST_0
                    IRETURN
  end public static boolean hasAspect()

  private static void ajc$postClinit()    org.aspectj.weaver.AjAttribute$AjSynthetic@1f0523b
:
                    NEW NameAspect
                    DUP
                    INVOKESPECIAL NameAspect.<init> ()V
                    PUTSTATIC NameAspect.ajc$perSingletonInstance LNameAspect;
                    RETURN
  end private static void ajc$postClinit()
end public class NameAspect

when weaving type NameAspect
when weaving aspects 
when weaving 
when batch building BuildConfig[D:\workspace\.metadata\.plugins\org.eclipse.ajdt.core\AspectSandBox.generated.lst] #Files=8
Comment 1 Jean-Sébastien Légaré CLA 2006-01-12 20:03:59 EST
Created attachment 32946 [details]
Contains 8 files (2 aspects, 4 annotations, 1 interface, 1 class) in one package (default package). Smallest application I could create that exhibits the bug. Everything is weaved on class Main. 

Same thing as the one cited in the bug's text (the URL).
Comment 2 Andrew Clement CLA 2006-01-17 08:45:55 EST
I've just checked the fix for this into AspectJ.  The NPE can no longer occur *but* that doesn't mean your program works as I've not spent time digging into whether it behaves as expected - but removing the NPE at least gets it compiling.
Comment 3 Andrew Clement CLA 2006-01-17 11:52:44 EST
fix for NPE is available in latest AspectJ dev build.  Will be in AJDT in a few days.