Community
Participate
Working Groups
On my project, when I save an aspect that calls an inter-type declaration defined on itself, the incremental compiler gives a message like this: The method logError(String, Exception) is undefined for the type Foo Foo.java Running a full build clears the error. This might be a compiler bug, or it might be AJDT (I never run command-line incremental compilation, so I don't know :-)). Unfortunately, simple test cases or extracts of just the 2 aspects aren't reproducing the issue, so let me know if you need me to spend some time trying to create a small isolated version of the issue.
Hi Ron - it is an AspectJ bug and I'm really keen to resolve errors in this space - based on your description I tried to recreate the problem but I can't seem to get it to fail. If you have time to look into it, I will fix it... In my attempt, I created two aspects: X.aj ---- public aspect X { before(): call(* *(..)) && !within(X) { Y.log(); } } Y.aj ---- public aspect Y { public void X.log() {} } --------- initially that advice doesn't exist in X and I build the system, then I change X to include it and do an incremental build - it doesn't fail :( But it's something very similar to that scenario that does fail. I think it only happens if you perform a sequence of saves and I believe ITDs have to be in the mix - but that's all I've managed to work out so far :( Any other constructs in your aspects? inlinable around advice? declares?
Andy, I was able to create the following small test case. Each of these types lives in its own source file. If you incrementally compile AbstractDerived, it fails. If you do a full rebuild it works... package sample; public abstract aspect AbstractBase { protected Holder member; } package sample; public abstract aspect AbstractDerived extends AbstractBase { Object x = getLogger(); } package sample; public interface Holder { } package sample; public aspect Logging { declare parents: sample.* && !Logging implements Loggable; public interface Loggable {} public Object Loggable.getLogger() { return null; } } Another interesting problem I ran into while weaving the same logging aspect using the AJ5 load-time weaving support was: java.lang.NegativeArraySizeException at org.aspectj.weaver.patterns.TypePatternList.read (TypePatternList.java:476) at org.aspectj.weaver.patterns.DeclareParents.read (DeclareParents.java:90) at org.aspectj.weaver.patterns.Declare.read(Declare.java:35) at org.aspectj.weaver.AjAttribute.read(AjAttribute.java:107) at org.aspectj.weaver.bcel.BcelAttributes.readAjAttributes (BcelAttributes.java:42) at org.aspectj.weaver.bcel.BcelObjectType.unpackAspectAttributes (BcelObjectType.java:191) at org.aspectj.weaver.bcel.BcelObjectType.<init> (BcelObjectType.java:98) at org.aspectj.weaver.bcel.BcelWorld.makeBcelObjectType (BcelWorld.java:239) at org.aspectj.weaver.bcel.BcelWorld.resolveObjectType (BcelWorld.java:234) at org.aspectj.weaver.World.resolveObjectType(World.java:151) at org.aspectj.weaver.World.resolve(World.java:130) at org.aspectj.weaver.World.resolve(World.java:109) at org.aspectj.weaver.World.resolve(World.java:147) at org.aspectj.weaver.tools.WeavingAdaptor.shouldWeaveAspect (WeavingAdaptor.java:206) at org.aspectj.weaver.tools.WeavingAdaptor.shouldWeave (WeavingAdaptor.java:185) at org.aspectj.weaver.tools.WeavingAdaptor.weaveClass (WeavingAdaptor.java:176) at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:74) at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform (ClassPreProcessorAgentAdapter.java:54) at sun.instrument.TransformerManager.transform (TransformerManager.java:122) ... This might have something to do with incompatibility between the loadtime5 branch and the AJDT milestone build that I'm using, but they are from the same epoch and generally work together, so it might not. Any idea why in the debugger it shows a length of -768?
Created attachment 20417 [details] Ajc compiled output that chokes the weaver... Here is the class file that is causing the weaver to choke. This may or may not be related to the original bug, but it's also an issue that we need to fix... I stepped through the weaving in the debugger and it is able to parse the type pattern but then chokes immediately when parsing the type pattern list. javap -v gives the following output, which shows the negative numbers: Compiled from "Logging.java" public class com.crankj.util.logging.Logging extends java.lang.Object implements com.crankj.util.logging.Logging$Loggable SourceFile: "Logging.java" InnerClass: public abstract #140= #64 of #2; //Loggable=class com/crankj/util/logging/Log ging$Loggable of class com/crankj/util/logging/Logging org.aspectj.weaver.Declare: length = 0x19C 02 08 01 01 00 04 00 03 63 6F 6D 00 06 63 72 61 6E 6B 6A 00 00 00 01 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 20 63 6F 6D 2E 63 72 61 6E 6B 6A 2E 75 74 69 6C 2E 6C 6F 67 67 69 6E 67 2E 4C 6F 67 67 69 6E 67 24 00 11 6A 61 76 61 2E 6C 61 6E 67 2E 4F 62 6A 65 63 74 24 00 18 63 6F 6D 2E 63 72 61 6E 6B 6A 2E 75 74 69 6C 2E 6C 6F 67 67 69 6E 67 2E 00 0A 6A 61 76 61 2E 6C 61 6E 67 2E 00 11 6F 72 67 2E 61 70 61 63 68 65 2E 6C 6F 67 34 6A 2E 00 00 00 FFFFFFDB 00 00 00 FFFFFFE7 07 06 01 01 00 06 00 03 63 6F 6D 00 06 63 72 61 6E 6B 6A 00 00 00 03 61 70 69 00 00 00 01 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 20 63 6F 6D 2E 63 72 61 6E 6B 6A 2E 75 74 69 6C 2E 6C 6F 67 67 69 6E 67 2E 4C 6F 67 67 69 6E 67 24 00 11 6A 61 76 61 2E 6C 61 6E 67 2E 4F 62 6A 65 63 74 24 00 18 63 6F 6D 2E 63 72 61 6E 6B 6A 2E 75 74 69 6C 2E 6C 6F 67 67 69 6E 67 2E 00 0A 6A 61 76 61 2E 6C 61 6E 67 2E 00 11 6F 72 67 2E 61 70 61 63 68 65 2E 6C 6F 67 34 6A 2E 00 00 00 FFFFFFEC 00 00 00 FFFFFFFD 07 07 00 00 00 FFFFFFEC 00 00 00 FFFFFFFD 00 00 00 FFFFFFDB 00 00 00 FFFFFFFD 00 01 02 01 00 2A 4C 63 6F 6D 2F 63 72 61 6E 6B 6A 2F 75 74 69 6C 2F 6C 6F 67 67 69 6E 67 2F 4C 6F 67 67 69 6E 67 24 4C 6F 67 67 61 62 6C 65 3B 00 00 07 00 00 01 0A 00 00 01 11 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00 00 00 FFFFFFCA 00 00 01 11 When I try to recompile the file using -inpath I get: illegal change to pointcut declaration: topLevelRequest(BindingTypePattern(javax .servlet.http.HttpServlet, 0)) illegal change to pointcut declaration: topLevelRequest(BindingTypePattern(javax .servlet.http.HttpServlet, 0)) org.aspectj.weaver.BCException: illegal change to pointcut declaration: topLevel Request(BindingTypePattern(javax.servlet.http.HttpServlet, 0)) at org.aspectj.weaver.patterns.ReferencePointcut.concretize1(ReferencePo intcut.java:275) at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:255) at org.aspectj.weaver.patterns.Pointcut.concretize(Pointcut.java:242) at org.aspectj.weaver.Advice.concretize(Advice.java:233) at org.aspectj.weaver.CrosscuttingMembers.addShadowMunger(CrosscuttingMe mbers.java:83) at org.aspectj.weaver.CrosscuttingMembers.addShadowMungers(CrosscuttingM embers.java:77) at org.aspectj.weaver.ResolvedTypeX.collectCrosscuttingMembers(ResolvedT ypeX.java:415) at org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect(Crosscut tingMembersSet.java:56) at org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave(BcelWeaver.java:37 9) at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.weave(AjCompiler Adapter.java:227) at org.aspectj.ajdt.internal.compiler.AjCompilerAdapter.afterCompiling(A jCompilerAdapter.java:119) at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compil er.java:385) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilat ion(AjBuildManager.java:683) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuild Manager.java:168) at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBu ildManager.java:102) at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:109) at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60) at org.aspectj.tools.ajc.Main.run(Main.java:291) at org.aspectj.tools.ajc.Main.runMain(Main.java:227) at org.aspectj.tools.ajc.Main.main(Main.java:80) 1 fail|abort, 2 errors The source file that generates this looks like this: package com.crankj.util.logging; import org.apache.log4j.*; public aspect Logging pertypewithin(Loggable) { private Logger logger; // don't put logging into the public API... declare parents: com.crankj..* &&!com.crankj..api..* implements Loggable; before() : staticinitialization(*) { logger = Logger.getLogger(thisJoinPointStaticPart.getSignature().getDeclaringType()); } public interface Loggable {} public void Loggable.logError(String message) { getLogger().error(message); } public void Loggable.logError(String message, Throwable throwable) { getLogger().error(message, throwable); } public Logger Loggable.getLogger() { return null; } // bizarre: need to advise yourself to get access to the instance associated with the ITD Logger around() : call(* Logging.getLogger()) { return logger; } }
Thanks for the example program Ron, I'll try that. I'm a little nervous about you working off the branch as that is very old now - as you are so keen on the LTW changes in it, we could think about moving them down into the base sooner rather than later. hmmm. Some of your problems really could be related to using a new AJDT and the branch for LTWing.
investigate for M3
Reached crunch time, now concentrating on just getting generics going for M3. Incremental problems are moving post M3
I have also encountered this problem (the incremental compilation part). Here is a minimal case to reproduce it. The interface and aspect each live in their own file. Each time I save the aspect file, the error appears and a clean is required to get rid of it. public interface Foo { } import java.util.ArrayList; import java.util.List; public aspect Bar { private List<String> Foo.l; private void Foo.foo() { l = new ArrayList<String>(); } }
From Ron DiFrango on the mailing list, here is another case of the same incremental bug, or a related one: Matt, As you point out, these are hard to re-produce. Maybe the steps [which is a combination of my previous two posts] that I used is as follows: Created the following aspect: package com.tascon.tim.sofia.aop; import com.salmonllc.jsp.JspTableRow; public aspect SofiaJspTableRow { pointcut generateHtml(JspTableRow row) : execution(public void JspTableRow.generateHTML(..)) && target(row); void around(JspTableRow row) throws java.io.IOException : generateHtml(row) { System.out.println("Executing my aspect now."); proceed(row); } } Performed an incremental compile [and deploy it to my App Server], then I modified that same aspect so that it resulted in the following; package com.tascon.tim.sofia.aop; public aspect SofiaJspTableRow { private DataStoreEvaluator JspTableRow._dsEval = null; /** * Use this method to bind this component to an expression in a DataStore * @param ds The DataStore to bind to. * @param expression The expression to bind to. * @see DataStoreEvaluator */ public void JspTableRow.setExpression(DataStoreBuffer ds, DataStoreExpression expression) throws Exception { // RRD: Error on this line because it can not see _dsEval this._dsEval = new DataStoreEvaluator(ds, expression); // RRD: Error on this line because it can not see _dsEval } pointcut generateHtml(JspTableRow row) : execution(public void JspTableRow.generateHTML(..)) && target(row); void around(JspTableRow row) throws java.io.IOException : generateHtml(row) { // RRD: Error on this line because it can not see _dsEval if (row._dsEval != null) { System.out.println("row._dsEval is NOT NULL."); } else { System.out.println("row._dsEval is null."); } proceed(row); } } Then, I attempted to perform another incremental compile with a call to this new method from another class and I got an error and could not compile until I did the full re-build. Also, this maybe of important note, these aspects affect only classes in a binary jar that I am weaving into. Ron
I think this is related to a bug I raised of my own, bug 108099. I plan to start work on it tomorrow... using all the nice examples in here as testcases :)
I hate incremental bugs. I managed to get Ron Bodkins scenario from comment #2 failing reliably in the AJ test harness. After some effort debugging it turns out to be exactly the same problem as I covered in bug 85132. The problem is that when AbstractDerived is saved for the second time, we have lost the declare parents information that AbstractBase implements Loggable - so we never discover the ITD on Loggable - and compilation fails. I'm trying to decide how much of a leap it is to conclude that incremental compilation of ITDs only goes wrong when used with declare parents... does everyone use declare parents with ITDs? This might certainly explain why I've had so much trouble recreating the problem. Ron DiFrangos program below doesn't appear to include any declare parents - but he is binary weaving ITDs into a jar which I think could be something else. Considering that we didn't have a problem for a while and that it suddenly got worse, I wonder if that coincided with the binary weaving declare parents work I did. Until I'd implemented binary decp we always modified the parents permanently - so in the example above, AbstractBase will always implement Loggable, even on the 2nd compile. I've been talking about the fix for this problem under bug 85132.
Fixed! See bug 85132. I'm raising comment #7 as a new bug since its generics related (bug 111779). waiting on build before closing. Ron (Bodkin), thanks so much for your test program!
fixed as per andy's last comment