Bug 148285 - [plan] [incremental] Exception when moving an aspect to it own source file...
Summary: [plan] [incremental] Exception when moving an aspect to it own source file...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 1.6.4   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-22 15:29 EDT by Ramnivas Laddad CLA
Modified: 2012-04-03 14:19 EDT (History)
2 users (show)

See Also:


Attachments
failing testcase (2.60 KB, patch)
2006-09-25 06:33 EDT, 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 2006-06-22 15:29:05 EDT
When I move a peer aspect (aspect in some other class' source file) to its own source, AJDT throws an exception during incremental compilation.

1. Start with a project with just the following source file:
package test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

public class Main {
	public static void main(String[] args) {
		new Main().foo();
	}
	
	@PerformenceMonitor(expected=1000)
	public void foo() {
		
	}
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface PerformenceMonitor {
	public int expected();
}

@Aspect
class Monitor {
	@Pointcut("execution(@PerformenceMonitor * *(..)) && @annotation(monitoringAnnot)")
	public void monitored(PerformenceMonitor monitoringAnnot) {}
	
	@Around("monitored(monitoringAnnot)")
	public Object flagExpectationMismatch(ProceedingJoinPoint pjp, PerformenceMonitor monitoringAnnot) {
		long start = System.nanoTime();
		Object ret = pjp.proceed();
		long end = System.nanoTime();
		
		if(end - start > monitoringAnnot.expected()) {
			System.out.println("Method " + pjp.getSignature().toShortString() + " took longer than expected\n\t"
					+ "Max expected = " + monitoringAnnot.expected() + ", actual = " + (end-start));
		}
		return ret;
	}
	
}

2. Create a new class -- Monitor (the same name as the aspect)
3. Cut and paste the Monitor aspect from Main.java to Monitor.java (keep the "package test;" statement).
4. Save All

The following exception is thrown:
java.lang.ClassCastException
at org.aspectj.ajdt.internal.core.builder.AjState.recordClassFile(AjState.java:783)
at org.aspectj.ajdt.internal.core.builder.AjState.noteResult(AjState.java:636)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager$3.acceptResult(AjBuildManager.java:884)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterProcessing(AjCompilerAdapter.java:206)
at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$afterReturning$org_aspectj_ajdt_internal_compiler_CompilerAdapter$4$6b855184(CompilerAdapter.aj:90)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:528)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:329)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:862)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:269)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:168)
at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117)
at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)

ClassCastException thrown: org.aspectj.weaver.MissingResolvedTypeWithKnownSignature

I tried it a few times. Definitely reproducable.
Comment 1 Matt Chapman CLA 2006-06-23 06:04:07 EDT
When I tried to reproduce this on Eclipse 3.2 + AJDT 1.4-latest, I got a different exception:

java.lang.ArrayIndexOutOfBoundsException
at org.aspectj.weaver.bcel.BcelWeaver.validateSingleBranchRecursion(BcelWeaver.java:693)
at org.aspectj.weaver.bcel.BcelWeaver.validateSingleBranchRecursion(BcelWeaver.java:676)
at org.aspectj.weaver.bcel.BcelWeaver.validateSingleBranchRecursion(BcelWeaver.java:675)
at org.aspectj.weaver.bcel.BcelWeaver.validateSingleBranch(BcelWeaver.java:645)
at org.aspectj.weaver.bcel.BcelWeaver.validateBindings(BcelWeaver.java:596)
at org.aspectj.weaver.bcel.BcelWeaver.rewritePointcuts(BcelWeaver.java:531)
at org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave(BcelWeaver.java:460)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:299)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:192)
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:887)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:271)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:170)
at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117)
at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)

ArrayIndexOutOfBoundsException thrown: 1


Anyway, both exceptions are coming from down in the compiler/weaver so I'm going to pass this over the fence :)
Comment 2 Andrew Clement CLA 2006-06-23 07:12:06 EDT
i've added a test and it reproduces Ramnivas' original exception - although he must be on an older version of AJ because we tidied it up to produce a more meaningful error than ClassCastException.  We now get:

java.lang.IllegalStateException: Type 'Ltest/Monitor;' not found in world!
	at org.aspectj.ajdt.internal.core.builder.AjState.recordWhetherCompilationUnitDefinedAspect(AjState.java:737)
	at org.aspectj.ajdt.internal.core.builder.AjState.noteResult(AjState.java:640)
	at org.aspectj.ajdt.internal.core.builder.AjBuildManager$2.acceptResult(AjBuildManager.java:909)
	at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterProcessing(AjCompilerAdapter.java:215)
	at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$after$org_aspectj_ajdt_internal_compiler_CompilerAdapter$4$6b855184(CompilerAdapter.aj:91)
	at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:533)
	at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:329)
	at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:887)
	at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:271)
	at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:170)
	at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117)
	at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)
Comment 3 Andrew Clement CLA 2006-06-23 08:19:16 EDT
testcase committed to MultiProjectIncremental but commented out.
Comment 4 Howard M. Lewis Ship CLA 2006-07-20 15:34:00 EDT
I'm getting the same, or similar stack trace under 3.1 (I can't upgrade to 3.2 because of plugin dependencies).

After commenting out most of my aspect I get the following:

public abstract aspect OneShotChecks extends AbstractClassTargetting
// perthis(annotatedClasses())
{
   pointcut annotatedClasses(): @within(OneShot) && targetClasses();
}

(Plus another "targetting" aspect):

public aspect InternalOneShotChecks extends OneShotChecks
{
    pointcut targetClasses()  :
        within(org.apache.tapestry..*);
}


When I uncomment out the perthis() line, I get the popup exception dialog.


I've actually been able to uncomment the rest of my aspect, except perthis(),
without errors, but the perthis() triggers this exception:

java.lang.ClassCastException
at org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor.getPerTypePointcut(PerThisOrTargetPointcutVisitor.java:41)
at org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor.visit(PerThisOrTargetPointcutVisitor.java:108)
at org.aspectj.weaver.patterns.AndPointcut.accept(AndPointcut.java:119)
at org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor.getPerTypePointcut(PerThisOrTargetPointcutVisitor.java:41)
at org.aspectj.weaver.PerObjectInterfaceTypeMunger.getTestTypePattern(PerObjectInterfaceTypeMunger.java:64)
at org.aspectj.weaver.PerObjectInterfaceTypeMunger.matches(PerObjectInterfaceTypeMunger.java:85)
at org.aspectj.weaver.ConcreteTypeMunger.matches(ConcreteTypeMunger.java:65)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:508)
at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:109)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1560)
at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:1511)
at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1291)
at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1089)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompilerAdapter.java:311)
at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(AjCompilerAdapter.java:183)
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:862)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:242)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:161)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:278)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:168)
at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117)
at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)

trouble in: 
public abstract class org.apache.tapestry.internal.aspects.AbstractClassTargetting extends java.lang.Object:
  public void <init>():
                    ALOAD_0     // Lorg/apache/tapestry/internal/aspects/AbstractClassTargetting; this   (line 24)
                    INVOKESPECIAL java.lang.Object.<init> ()V
    constructor-execution(void org.apache.tapestry.internal.aspects.AbstractClassTargetting.<init>())
    |               RETURN
    constructor-execution(void org.apache.tapestry.internal.aspects.AbstractClassTargetting.<init>())
  end public void <init>()

  abstract void ajc$pointcut$$targetClasses$4e2()    org.aspectj.weaver.MethodDeclarationLineNumber: 30:1250
;

end public abstract class org.apache.tapestry.internal.aspects.AbstractClassTargetting

when weaving type org.apache.tapestry.internal.aspects.AbstractClassTargetting
when weaving aspects 
when weaving 
when batch building BuildConfig[C:\workspace\.metadata\.plugins\org.eclipse.ajdt.core\tapestry-core.generated.lst] #Files=208

Here's the aspect I'm trying to write:

public abstract aspect OneShotChecks extends AbstractClassTargetting
perthis(annotatedClasses())
{
    private boolean _oneShotLock;

    pointcut annotatedClasses(): targetClasses() && @within(OneShot);

    /** Method inherited from java.lang.Object are never locked. */
    pointcut excludedMethods() :
        execution(public int hashCode()) ||
        execution(public boolean equals(Object)) ||
        execution(public String toString());

    /** Locked methods are within annotated classes, aren't excluded, and are public. */
    pointcut lockedMethods() :
        annotatedClasses() && ! excludedMethods() && execution(public * *(..));

    /** Methods with the OneShot.Lockdown annotation will set the lock. */
    pointcut lockingMethods() : lockedMethods() && execution(@OneShot.Lockdown * *(..));

    // I'm a little shakey on the order of execution for this pair of advice.
    // For a locking method, we should do the check first, then set the lock.

    before() : lockingMethods()
    {
        _oneShotLock = true;
    }

    before() : lockedMethods()
    {
        if (_oneShotLock)
            throw new IllegalStateException("Method " + thisJoinPointStaticPart.getSignature()
                    + " may no longer be invoked.");
    }

}
Comment 5 Howard M. Lewis Ship CLA 2006-07-20 15:37:12 EDT
Getting better results using:

public abstract aspect OneShotChecks extends AbstractClassTargetting
perthis(annotatedClasses())
{
    private boolean _oneShotLock;

    pointcut annotatedClasses(): targetClasses() && within(@OneShot Object+);
Comment 6 Andrew Clement CLA 2006-08-23 09:06:17 EDT
the test I created in comment #3 is now passing - not quite sure what that means, but thought I'd say... ;)
Comment 7 Helen Beeken CLA 2006-09-25 06:33:40 EDT
Created attachment 50809 [details]
failing testcase

Apply this patch to the tests project.

I've recreated the stacktrace in comment #2 (java.lang.IllegalStateException: Type 'LC;' not found in world!) with HEAD and a simplified testcase. The recreate steps are:

1. Create an aspect that has some advice (A.aj)
2. Within the same file (A.aj) create a class C that is affected by the advice
3. Create a new file for this class (C.java) and copy contents 
4. Save and get a "The type C is already defined" error
5. Comment out/delete class C from A.aj and save
Comment 8 Andrew Clement CLA 2009-02-01 11:44:28 EST
closing this - done all the work I plan to do on it (tests and guards). the final testcase in here has been put into the AJ regression suite and runs fine.  I haven't seen:

java.lang.ClassCastException
at
org.aspectj.ajdt.internal.core.builder.AjState.recordClassFile(AjState.java:783)

for a long time, nor

java.lang.ArrayIndexOutOfBoundsException
at
org.aspectj.weaver.bcel.BcelWeaver.validateSingleBranchRecursion(BcelWeaver.java:693)

which I think is a dup now I come to think of it, but won't dig through the other reports right now.

This:

java.lang.IllegalStateException: Type 'Ltest/Monitor;' not found in world!
        at
org.aspectj.ajdt.internal.core.builder.AjState.recordWhetherCompilationUnitDefinedAspect(AjState.java:737

cant happen any more. And this:

java.lang.ClassCastException
at
org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor.getPerTypePointcut(PerThisOrTargetPointcutVisitor.java:41)

if it happens again somehow (I haven't ever seen it), will produce better diagnostics for me rather than just the CCE.