Community
Participate
Working Groups
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.
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 :)
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)
testcase committed to MultiProjectIncremental but commented out.
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."); } }
Getting better results using: public abstract aspect OneShotChecks extends AbstractClassTargetting perthis(annotatedClasses()) { private boolean _oneShotLock; pointcut annotatedClasses(): targetClasses() && within(@OneShot Object+);
the test I created in comment #3 is now passing - not quite sure what that means, but thought I'd say... ;)
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
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.