I presume all these aspects are being compiled together with the code. You shouldn't have to worry about that order the aspects are applied in - yes there are ITDs but the weaver considers the system as a whole and will apply the aspects to ITD'd methods as well as existing methods:
public class Code {
public void moo(String s) {}
}
aspect X {
public void Code.boo(String s) {}
}
aspect Y {
before(): execution(* *(String)) {}
}
> ajc -showWeaveInfo Code.java X.java Y.java
Join point 'method-execution(void Code.boo(java.lang.String))' in Type 'X' (X.java:2) advised by before advice from 'Y' (Y.java:2)
Type 'Code' (Code.java) has intertyped method from 'X' (X.java:'void Code.boo(java.lang.String)')
Join point 'method-execution(void Code.moo(java.lang.String))' in Type 'Code' (Code.java:2) advised by before advice from 'Y' (Y.java:2)
Precedence only affects advice, not ITDs. The advice is being applied to the ITDs, not to what you imagine is happening under the covers (the methods being stuffed into the target, hence you think you need to get that done first). All ITDs (and declares) are processed to ensure the type system is coherent and then the advice is applied.
I feel like we used to have problems in this area but I thought they were all fixed up. Worth raising an AspectJ issue. If you can provide a simple test case that shows it failing (unlike mine which shows it working) that would be really useful. Maybe if any of the annotations you are triggering on are being applied by declare, try putting them directly on the methods of interest and temporarily removing the declare - does that make a difference. It may be the interplay between declare/itd and advice.
cheers,
Andy