Bug 160868 - [build] Infinite loop of builds when errors occur while Build Automatically turned on
Summary: [build] Infinite loop of builds when errors occur while Build Automatically t...
Status: NEW
Alias: None
Product: AJDT
Classification: Tools
Component: Core (show other bugs)
Version: 1.4.0   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: AJDT-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-13 10:40 EDT by Mitsu Hadeishi CLA
Modified: 2013-01-29 00:45 EST (History)
3 users (show)

See Also:


Attachments
Redacted AJDT trace log (876.51 KB, text/plain)
2006-10-15 23:16 EDT, Mitsu Hadeishi CLA
no flags Details
A four project test case for this bug (12.95 KB, application/octet-stream)
2008-03-20 17:57 EDT, Jason Naylor CLA
no flags Details
annotated event trace (21.67 KB, text/plain)
2008-04-09 17:16 EDT, Andrew Clement CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mitsu Hadeishi CLA 2006-10-13 10:40:15 EDT
Quite frequently while I have been trying to use AJDT the plugin will display spurious errors such as "Syntax error on token "aspect", interface expected".  Another person reported a similar error here:

http://www.mail-archive.com/aspectj-users@eclipse.org/msg00376.html

They suggested cleaning the project --- however, when I do this, the build proceeds in an infinite loop to build and rebuild over and over, and it never halts.  The only way to stop it is to turn off building automatically --- a manual build will sometimes eliminate the error, but only temporarily --- if I edit the aspect file again, the error will return.
Comment 1 Matt Chapman CLA 2006-10-13 10:53:19 EDT
The infinite build loop sounds more serious than the mistaken errors! You could try opening the AJDT Event Trace view and using the filter button to select all the trace categories, and then try cleaning the project.
Also, can you try the latest development build of AJDT 1.4.1 on Eclipse 3.2? Have you encountered the problem on Windows or Linux, or only Mac OS? (we do some testing on a Mac).

Do you have any other plugins installed?
Comment 2 Mitsu Hadeishi CLA 2006-10-13 11:06:18 EDT
I seem to have solved the problem --- at least at the moment, updating to Eclipse 3.2.1 seems to have stopped the error.  I will leave this bug open for the moment to see if it stays solved as I work with it.
Comment 3 Mitsu Hadeishi CLA 2006-10-13 19:02:34 EDT
Okay, updating to 3.2.1 helped, but I got the infinite loop project build problem again (though not the 'aspect should be interface' spurious error problem).  Investigating further, I determined the only way to prevent the infinite loop project build problem was to turn off build automatically and eliminate all errors, then once I had done a rebuild all with no errors, build automatically worked again without the infinite loop problem.
Comment 4 Mitsu Hadeishi CLA 2006-10-14 17:38:36 EDT
Okay, so updating to 3.2.1 did fix the spurious error, but does not fix the infinite loop in building and rebuilding my project. I'm changing the subject line of this bug accordingly, to focus on the infinite loop.

I installed the latest development build of the AJDT plugin (1.4.1.200610100440) into Eclipse 3.2.1 and still get this problem: whenever there is an error in a class that is being advised by an aspect (for example, in the case I just tested, I defined some methods on an interface via an intertype declaration, and it works fine, but if I change the name of the method but don't update code that calls the method, it reports an error and then restarts the build, over and over again).

It starts over at "40%" and proceeds through "compiling source files" but instead of stopping after the compile, it restarts the build again from 40%, etc.

Here's the AJDT event trace:

5:34:52 PM Startup information: 
   AJDT version: 1.4.1.200610100440 for Eclipse 3.2
   AspectJ Compiler version: DEVELOPMENT
   usingVisualiser=true
   usingXref=true
   usingCUprovider=false
   doneAutoOpenXRefView/Volumes/Encrypted/workspace = true
   ajde.version.at.previous.startup = @AJDEVERSION@
5:35:02 PM ===========================================================================================
5:35:02 PM Build kind = AUTOBUILD
5:35:02 PM Project=arcturus-core, kind of build requested=Incremental AspectJ compilation
5:35:02 PM build: Examined delta - no source file changes for project arcturus-core
5:35:02 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:02 PM Falling back to batch compilation
5:35:02 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:03 PM Timer event: 700ms: Time to first compiled message
5:35:05 PM AJDE Callback: finish. Was full build: true
5:35:05 PM Timer event: 3008ms: Total time spent in AJDE
5:35:05 PM Timer event: 104ms: Create element map (0 rels in project: arcturus-core)
5:35:05 PM Types affected during build = 368
5:35:05 PM Timer event: 1ms: Add markers (0 markers)
5:35:05 PM Timer event: 3382ms: Total time spent in AJBuilder.build()
5:35:05 PM ===========================================================================================
5:35:05 PM Build kind = AUTOBUILD
5:35:05 PM Project=arcturus-core, kind of build requested=Incremental AspectJ compilation
5:35:05 PM build: Examined delta - no source file changes for project arcturus-core
5:35:05 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:05 PM Falling back to batch compilation
5:35:05 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:06 PM Timer event: 749ms: Time to first compiled message
5:35:08 PM AJDE Callback: finish. Was full build: true
5:35:09 PM Timer event: 3331ms: Total time spent in AJDE
5:35:09 PM Timer event: 91ms: Create element map (0 rels in project: arcturus-core)
5:35:09 PM Types affected during build = 368
5:35:09 PM Timer event: 0ms: Add markers (0 markers)
5:35:09 PM Timer event: 3697ms: Total time spent in AJBuilder.build()
5:35:09 PM ===========================================================================================
5:35:09 PM Build kind = AUTOBUILD
5:35:09 PM Project=arcturus-core, kind of build requested=Incremental AspectJ compilation
5:35:09 PM build: Examined delta - no source file changes for project arcturus-core
5:35:09 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:09 PM Falling back to batch compilation
5:35:09 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:10 PM Timer event: 846ms: Time to first compiled message
5:35:13 PM AJDE Callback: finish. Was full build: true
5:35:13 PM Timer event: 3417ms: Total time spent in AJDE
5:35:13 PM Timer event: 106ms: Create element map (0 rels in project: arcturus-core)
5:35:13 PM Types affected during build = 368
5:35:13 PM Timer event: 0ms: Add markers (0 markers)
5:35:13 PM Timer event: 3781ms: Total time spent in AJBuilder.build()
5:35:13 PM ===========================================================================================
5:35:13 PM Build kind = AUTOBUILD
5:35:13 PM Project=arcturus-core, kind of build requested=Incremental AspectJ compilation
5:35:13 PM build: Examined delta - no source file changes for project arcturus-core
5:35:13 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:13 PM Falling back to batch compilation
5:35:13 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:14 PM Timer event: 847ms: Time to first compiled message
5:35:17 PM AJDE Callback: finish. Was full build: true
5:35:17 PM Timer event: 3741ms: Total time spent in AJDE
5:35:17 PM Timer event: 112ms: Create element map (0 rels in project: arcturus-core)
5:35:17 PM Types affected during build = 368
5:35:17 PM Timer event: 0ms: Add markers (0 markers)
5:35:17 PM Timer event: 4122ms: Total time spent in AJBuilder.build()
5:35:18 PM ===========================================================================================
5:35:18 PM Build kind = AUTOBUILD
5:35:18 PM Project=arcturus-core, kind of build requested=Incremental AspectJ compilation
5:35:18 PM build: Examined delta - no source file changes for project arcturus-core
5:35:18 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:18 PM Falling back to batch compilation
5:35:18 PM Preparing for build: not going to be incremental because no successful previous full build
5:35:19 PM Timer event: 891ms: Time to first compiled message
5:35:22 PM AJDE Callback: finish. Was full build: true
5:35:22 PM Timer event: 4197ms: Total time spent in AJDE
5:35:22 PM Timer event: 107ms: Create element map (0 rels in project: arcturus-core)
5:35:22 PM Types affected during build = 368
5:35:22 PM Timer event: 0ms: Add markers (0 markers)
5:35:22 PM Timer event: 4600ms: Total time spent in AJBuilder.build()

Fixing the errors while "Build Automatically" is turned off will stop the endless loop of builds.

I have the following plugins installed:

ANTXR 0.9.0 and ANTLR 4.1.1 plugins (neither were enabled for the project in question during the above test)

Standard Eclipse 3.2.1 plugins (Java Development Tools, JDT Plug-in Developer Resources, PDE Plug-in Developer Resources, Platform, Platform Plug-in Developer Resources, Plug-in Development Environment)

FreeMarker 0.3.1

Jetty Launcher 1.4.1

Mylar Integration 1.0.0

Subversive 1.1.0.M5
Comment 5 Mitsu Hadeishi CLA 2006-10-14 17:50:25 EDT
Fiddling with this some more, I discovered more precisely how to reproduce this bug.  Basically, editing an aspect definition that introduces an error in Java code will cause the infinite loop when Build Automatically is on.  I.e., NOT simply creating an error in the aspect definition itself, but an error that cascades to an error in Java code.  For example, I have an aspect that introduces a method into all classes that implement a certain interface.  Suppose I have some Java code that calls that method.  If I delete or rename the method in the aspect, it will cause a syntax error in the Java source code saying "method not defined".  This sort of error will trigger the infinite loop; the only way to stop it is, as noted above, to turn off Build Automatically, fix the error, clean and rebuild, and then turn Build Automatically back on.
Comment 6 Mitsu Hadeishi CLA 2006-10-14 18:55:20 EDT
Okay I figured out the dependency: the problem only occurs when the Subversive plugin is installed; I have version 1.1.0.M5.  With Subversive disabled, the problem does not occur --- with it enabled it does occur.  I am going to try downloading the latest Subversive plugin.
Comment 7 Mitsu Hadeishi CLA 2006-10-14 19:24:22 EDT
Still happening with Subversion 1.1.0.M6.  Will report this bug on the Subversion site as well.
Comment 8 Matt Chapman CLA 2006-10-15 04:40:51 EDT
Great job narrowing the problem down. We'll see if we can reproduce the problem after installing Subversive. Does the failing project need to be checked out from a SVN repository to show the problem, or is just the plugin being active sufficient?
Comment 9 Mitsu Hadeishi CLA 2006-10-15 10:20:36 EDT
I just tried disconnecting all my projects from the Subversion repository and the error stopped occurring.  However, I haven't yet tried creating a project from scratch, sharing it, and seeing if the error happens.  One thing that might be of interest is that I have several related projects, all of which are shared with Subversive, and some of the projects depend on the others (i.e., one project creates libraries used by another).  I did try disconnecting just the project with the error, and the infinite loop DID still occur -- but disconnecting all projects stopped the error.  Re-sharing just the project with the error also seemed to be enough to cause the error.

I am not sure if the error only happens if you have two projects, both shared with Subversive, which depend on each other.

In this case, only one project has any AspectJ code in it.
Comment 10 Mitsu Hadeishi CLA 2006-10-15 14:47:16 EDT
Okay, more info.  I tried copying the project and paring it down to see if I can reproduce the problem on a more minimal-sized project.  Unfortunately, after I deleted a bunch of stuff that wasn't directly related to AspectJ, the project stopped building infinitely --- though it will rebuild a few times --- just not indefinitely.

The dependent project thing doesn't seem to be a factor --- the copied project was standalone (no other project depended on it) but the infinite rebuild still occurred.  Unfortunately, however, reproducing this seems to be related to the complexity/size of the project in some way.  Note that we just started to add aspects into this particular project, so, while it has a number of classes/files, the error seems to happen with just a few aspect files.

It still does seem odd that the project rebuilds itself a few times.  Oddly enough, the number of times it rebuilds seems to vary depending on the exact error.  For example, if I rename the inter-type declaration method from "toLongString()" to "toLongString1234123412341512316134513451235" it will rebuild itself 7 times before stopping, but if I rename it to "toLongString2" it will only rebuild itself 6 times, and renaming it to "toLongString12341232351235126134561461251351235153412341512316134513451235", it only rebuilds itself twice!
Comment 11 Mitsu Hadeishi CLA 2006-10-15 14:50:25 EDT
Yet another note: it's not the specific error that determines the number of rebuilds -- it's random.  With the pared-down project, it sometimes rebuilds itself twice, sometimes 6 times, sometimes 8 times.  So clearly the rebuild problem seems to be timing related.  Perhaps that's why the more complex project rebuilds itself indefinitely --- somehow, the longer it takes to rebuild, the more likely it will trigger the re-rebuild.
Comment 12 Matt Chapman CLA 2006-10-15 17:09:11 EDT
Please could you try opening the AJDT Event Trace view and using the filter button on the view's toolbar to select all of the Compiler related trace categories, then paste in here the output from a multiple rebuild.
Comment 13 Mitsu Hadeishi CLA 2006-10-15 23:15:24 EDT
Oh, now this is strange.  When I turn on the compiler debugging messages, the infinite rebuild loop doesn't happen continuously.  Instead, it built itself, then again, then paused for a few minutes, then built itself again, then paused, then built itself again, etc.  Unfortunately I can't paste in the full debug output because it contains hints about some proprietary architecture we're using which I'm not authorized to divulge publically yet.  However, I am attaching a subset of the log with the filenames removed which I hope will give you enough information.  If you need more, let me know and I can fiddle with the log.
Comment 14 Mitsu Hadeishi CLA 2006-10-15 23:16:30 EDT
Created attachment 52012 [details]
Redacted AJDT trace log
Comment 15 Steve Young CLA 2006-10-18 07:03:08 EDT
With Eclipse 3.2.1, AJDT 1.4.1.200610100440 and Subversion 1.1.0.M6, I don't see the problem. Having said that, I can't get Subversion to work with any of the public respositories I tried, so if there's one we could agree to use for the purpose of recreating this problem, that would help (e.g. http://svn.tmate.org/repos/jsvn gives "There is an error occured while accessing the repository entry" in Subversion, but works fine under RapidSVN).

At any rate, simply having the Subversion plugin installed and active doesn't create the recursive build problem for me, with two AspectJ projects open; changing the method name in an introduced method in one project causes an error in the advised class in the other project, but that's it.

I've also set up a Subversion server on my machine, added my two projects to it successfully, then checked them out to a separate workspace via the Subversive plugin (which works fine for all this). I still do not get the looping build behaviour, just the expected error in the advised class.
Comment 16 Mitsu Hadeishi CLA 2006-10-18 11:36:07 EDT
I tried the same thing with a small project --- the looping build doesn't occur either.  It only seems to happen with a large project.  What I don't know is if there is something particular about MY project that is causing this, or if it is just the size.  Did you try this with a relatively large project, or did you try it only with a small test project?

I will try to make time to set up a Subversion server for you to try out.  We're using a server on our intranet with svn+ssh protocol.
Comment 17 Eclipse Webmaster CLA 2007-07-29 09:21:01 EDT
Changing OS from Mac OS to Mac OS X as per bug 185991
Comment 18 Jason Naylor CLA 2007-12-07 12:44:00 EST
I have been able to reproduce the rebuilding problem with a small 3 project test case.  

I created an AspectJ project AspectProjectOne, with a class AspectTargetOne in the package testing.one.  I gave the class a default constructor and nothing else.  

Next I created an AspectJ project AspectProjectTwo and a class AspectTargetTwo in the testing.two package.  I created a default constructor and a void function with a string parameter. 

I created a third project called CreateBuildProblems as a Java project(not an AspectJProject).  In the CreateBuildProblems project I created a class PainInstigator in the testing.pain package. It has two member variables one AspectTargetOne, and one of AspectTargetTwo which I instantiate.

Then I created an aspect TargetModifier in the package testing.one, with the following code: 
--Begin Code--
package testing.one;

import testing.two.AspectTargetTwo;

public aspect TargetModifier {
   AspectTargetOne thisAgent = null;
   static int callCount = 0;
   after(AspectTargetOne agent) : execution(public AspectTargetOne.new(..)) && target(agent) {
      thisAgent = agent;
   }
   private pointcut recheckTriggers(AspectTargetTwo item) : 
      (execution(void AspectTargetTwo.breakSomething(String)) && target(item));      
      
   after(AspectTargetTwo item) : recheckTriggers(item) {
      if(thisAgent != null) {
         callCount++;
      }
   }
}
--End Code--
Give the CreateBuild project dependencies on both other projects.
Make AspectTargetOne have a project dependency on AspectTargetTwo
Add an AspectTargetOne to the AspectTargetTwo AspectJ Build Inpath.

When eclipse does the workspace auto save it will trigger a rebuild when automatic builds are one.  I tried to trace through the code to fix this and I found that in the RefreshLocalVisitor class, in the visit function (~line 281) it finds that the class files are out of sync, this is what triggers the rebuild.

Well, forgive me for this long winded comment, but I hope it helps.
Comment 19 Jason Naylor CLA 2007-12-07 13:14:51 EST
My apologies, in my previous comment I neglected to mention the following info:
OS: Windows XP SP2
Eclipse Version: 3.3.0, Build ID: I20070625-1500
AJDT Version: 1.5.0.200706070619
AspectJ Version: 1.5.4.200705211336
Comment 20 Andrew Clement CLA 2007-12-13 18:52:25 EST
Hi Jason,
We are quite limited on resource at the moment across AJDT and AspectJ (this is due to change as we are hiring more people to work full time on these areas).  It is very useful that you narrowed it down to a simple scenario as that really can be half the battle...  I can't work on this right now as AspectJ 1.6.0 is taking up all of my time, but if I can help you navigate the AJDT code in some way, let me know.
Comment 21 Andrew Clement CLA 2008-03-17 13:41:52 EDT
I just followed the instructions to create the failing scenario in comment #18.  I am only Eclipse 3.3.2 with a recent AJDT (1.5.2 dev build).  It doesn't loop for me - once fully defined and consistent, I can make a whitespace change in any of the files and I see a couple of projects build and then it is fine.  I wonder what I am doing differently to you?  I know i'm on a different level of AJDT but I don't know of any fixes that have gone in to address anything like this.

I then did a clean of all projects and it was also OK.  Once everything is building OK for you, where do you make a change to autosave and cause infinite rebuilds?

This circular dependency worries me and I could see that triggering infinite rebuilds:

> Make AspectTargetOne have a project dependency on AspectTargetTwo
> Add an AspectTargetOne to the AspectTargetTwo AspectJ Build Inpath.

By 'add an aspecttargetone' I presume you mean adding the bin folder of the AspectTargetOne project?

Is this workspace on a FAT32 filesystem by any chance?  Have you tried the most recent AJDT builds or are you still on 1.5.0 ?

(The original problems in here to do with subversion were addressed (I think) by telling AspectJ to ignore the .svn files that get littered through the projects when the projects are linked to subversion - these files were looking like file system changes to AJ so it repeatedly built)
Comment 22 Jason Naylor CLA 2008-03-17 16:21:20 EDT
> This circular dependency worries me and I could see that triggering infinite
> rebuilds:
> 
> > Make AspectTargetOne have a project dependency on AspectTargetTwo
> > Add an AspectTargetOne to the AspectTargetTwo AspectJ Build Inpath.
> 
> By 'add an aspecttargetone' I presume you mean adding the bin folder of the
> AspectTargetOne project?

Yes, this is what I meant.
 
> Is this workspace on a FAT32 filesystem by any chance?  Have you tried the most
> recent AJDT builds or are you still on 1.5.0 ?

The workspace is on an NTFS file system.

> I just followed the instructions to create the failing scenario in comment #18.
>  I am only Eclipse 3.3.2 with a recent AJDT (1.5.2 dev build).  It doesn't loop
I will try and update Eclipse, I am currently on 3.3.1.1.  In the release notes for 3.3.2 I found a bug that could be related, bug 210746.  I will update with the results when I get a chance to try 3.3.2.
Comment 23 Jason Naylor CLA 2008-03-20 17:57:39 EDT
Created attachment 93074 [details]
A four project test case for this bug
Comment 24 Jason Naylor CLA 2008-03-20 17:59:32 EDT
(In reply to comment #22)
> >  I am only Eclipse 3.3.2 with a recent AJDT (1.5.2 dev build).  It doesn't loop
> I will try and update Eclipse, I am currently on 3.3.1.1.  In the release notes
> for 3.3.2 I found a bug that could be related, bug 210746.  I will update with
> the results when I get a chance to try 3.3.2.

I updated to Eclipse 3.3.2 and the latest AJDT release for Eclipse 3.3 and the test case that I added here was not reproducible. 

However, when I loaded up our actual project workspace the bug was still apparent.

I managed to create another test case which reproduces the bug, but it is a little more involved then the previous one.  I have zipped up the test case and some instructions which I attached in comment #23
Comment 25 Andrew Clement CLA 2008-03-20 20:34:29 EDT
Hi Jason,

whoa, that's a complicated scenario ;)

I'm trying to recreate it now but not quite sure if I'm seeing what you are seeing.

> Whenever the workspace save wakes up a build will run, and the workspace save will remain in the progress view.

When the workspace save wakes up, I see the build, then it drops back to 'System: periodic workspace save. (Sleeping)' and nothing else is happening.  Do you not think the build should happen on that auto save? or do you see the periodic workspace save thread not going back to sleep?

> Also, there is a potentially unrelated bug that can be seen in this setup.  The Cross References view for the TargetModifier.aj in the AspectContainer project does not show any links, but running the CreateBuildProblems (if you run it between the ever running builds) shows that the aspect was applied to both projects.
   
There is something peculiar here, from my point of view the projects themselves look a bit tangled up.

I have:
AspectContainer
AspectProjectOne
AspectProjectTwo

AspectContainer has AspectProjectOne and AspectProjectTwo as both project dependencies and as inpath dependencies.   But then I see AspectProjectOne and AspectProjectTwo have AspectContainer/bin on their aspectpath?  I see that as a bit of a circular dependency.  Why has AspectContainer got inpath dependencies on AspectProjectOne and AspectProjectTwo?  Is it just to trigger this bug?  If you tried to make them co-depend on each other with regular JDT project dependencies there would be a cycle detected error reported so I wonder if this is just a circular dependency that AJDT should be flagging (avoiding the issue of repeatedly building then as it couldn't be setup this way).  I can imagine it would loop when setup like this, and I could see it impacting the cross references view.

If AspectContainer needs a dependency on the other projects just so the aspect will compile then that would be just a project/classpath dependency and not an inpath dependency.

maybe I should ask how you want to use the AJDT projects in your real scenario and we can see if they are configured the right way round?
Comment 26 Jason Naylor CLA 2008-03-21 17:38:28 EDT
(In reply to comment #25)
> Hi Jason,
> 
> whoa, that's a complicated scenario ;)

Yes it is.  But at least it's small. :)
 
> When the workspace save wakes up, I see the build, then it drops back to
> 'System: periodic workspace save. (Sleeping)' and nothing else is happening. 
> Do you not think the build should happen on that auto save? or do you see the
> periodic workspace save thread not going back to sleep?

The build should not occur on the workspace save unless something has changed, and nothing has.  In our actual project when this problem occurred our workspace save time was 5 minutes, and our build lasts more than 7.  Hence infinite re-building.

> There is something peculiar here, from my point of view the projects themselves
> look a bit tangled up.

Rather than comment specifically on each remaining point about our screwy test case I'll just try to give a 'brief' explanation.

The projects are tangled mostly because I was trying to get the bug to re-produce on a smaller scale then our 55 project, 200,000 line(and growing) application.  

For this test case to accurately show what we might encounter the AspectContainer project would have the 'Inpath' entries, but AspectProject(One|Two) would not have the 'Aspect Path' entires.  In practice I do not actually want the 'Aspect Path' entries in this test case.  However, while the build runs without them it doesn't seem to weave.  When I added the 'Aspect Path' entries, the code is woven correctly, but the infinite re-building begins.  

To accurately match what we are trying to do in our application AspectProjectOne can not know about AspectProjectTwo.  AspectProjectOne and AspectProjectTwo should not know about AspectContainer.  AspectContainer can know about everyone.  If you remove the 'Inpath' entries from the AspectContainer class and put just the 'Aspect Path' entries then AspectProjectOne will not build because it needs to know about AspectProjectTwo and vice versa.

As to the circular dependency issue; if this is truly a circular dependency, I think it would be appropriate to flag that as an error.  It was my understanding the 'Inpath' for AspectContainer and the 'AspectPath' in AspectProjectOne are serving the same purpose.  

However I am not convinced that we have this condition in our main application, so I would like to see the re-building investigated irregardless.  To me it looks like there is some accounting of build completion that is going wrong, if it is a result of a circular dependency  which is hidden in our application then so be it.

So after this small novella is there anything else that needs clearing up? ;)

Oh and thanks for looking at this Andy,
Jason
Comment 27 Andrew Clement CLA 2008-04-09 17:16:27 EDT
Created attachment 95428 [details]
annotated event trace
Comment 28 Andrew Clement CLA 2008-04-09 17:27:48 EDT
I am back to looking at this.

Let me define inpath and aspectpath for my own benefit when looking into this
- Any code on the inpath is woven into the project in question *and also written* to the output folder of the project.
- Any aspects on the aspectpath are woven into the project *but not written* to the output folder of the project.  (So to execute the code you need the classpath to include the same as the aspectpath).

Here we have Container which has an inpath of ProjectOne, ProjectOne has an aspectpath dependency on Container. (ignoring ProjectTwo for now)

Change AspectTargetOne in AspectProjectOne, it will rebuild - applying aspects from AspectContainer in what gets produces in AspectTargetOne/bin.  Then AspectContainer will be rebuilt (it depends upon AspectProjectOne) - AspectContainer includes an inpath of AspectProjectOne/bin and so all the .class files from AspectProjectOne will be copied into AspectContainer and the aspects will be applied from AspectContainer (again).  This changes the .class files in the bin folder of AspectContainer - and that ought to require a rebuild of AspectProjectOne, which will see all new class files in AspectContainer/bin and rebuild again.  However, I don't see the second rebuild of AspectProjectOne, possibly because of the limited refresh that occurs in the case of AJDT project builds in the AJBuilder.  Effectively we seem to be in a cyclic dependency but are getting away with it settling down when it shouldn't.

I don't think I would recommend mixing up aspectpath and inpath like this making two projects co-dependent.

I've attempted to annotate a build log of a whitespace change to AspectTargetOne, it is attached to this bug report.  Just to try and make sense of what I see - but so far it doesn't make complete sense.

> As to the circular dependency issue; if this is truly a circular dependency, I
> think it would be appropriate to flag that as an error.  It was my
> understanding the 'Inpath' for AspectContainer and the 'AspectPath' in
> AspectProjectOne are serving the same purpose. 

inpath and aspectpath are rather different, as I mentioned at the top of this post.  Are you using them both just in order to see gutter annotations for advised code?

Finally, as I mention in my annotated trace, I don't understand why the periodic save thread remains dormant (asleep) after the first save and then repeats its job later.  As Jason says:

> To me it looks like there is some accounting of build completion that is 
> going wrong

I possibly agree, but I don't know anything about JDT internals for the periodic save behaviour, so I might transfer this back to being an AJDT bug.  The only thing I might like to fix in AspectJ is better incremental support for inpath, but that won't be in 1.6.0.

I'd like to understand what you want to achieve with inpath/aspectpath mixed up like this and see if we can setup the project dependencies in a more appropriate way that will work for you?
Comment 29 Andrew Clement CLA 2008-04-09 18:21:54 EDT
There seem to be a few issues in here, all mixed up together which is stopping me thinking straight about any individual one.  Let's try and enumerate them:

1) Project builds. After changing AspectProjectOne, we see it rebuild, but why does AspectProjectTwo rebuild?

2) Classpath. Why is the AspectContainer/bin folder on the AspectProjectOne classpath multiple times.  Can we limit the number of times it is there, or improve AjState so it avoids repeating analysis for the same element twice.

3) Periodic save.  Why does the periodic save thread continue to persist, only disappearing after a 'couple of minutes' (with periodic save set to 1min).  What does it mean for the periodic save thread to be asleep rather than not running - is it waiting for 1min of quiet before saving?

4) Cyclic dependencies. Should the mixing up of aspectpath/inpath between two projects be reported as a cyclic dependency problem between two projects

5) Refreshes ok?  If it is a cyclic dependency, why do we not see infinite rebuilds all the time for the AspectContainer and AspectProjectOne projects?  Is the refresh logic in AJDT AJBuilder incorrect?

6) Inpath enhancement.  Can we improve the analysis of inpath elements to determine if they require us to build, rather than just looking at the timestamp.

7) Diagnostics.  What diagnostics can we add to AJDT event trace to make any of 1-6 more clear...
Comment 30 Jason Naylor CLA 2008-04-09 19:44:09 EDT
(In reply to comment #29)
> There seem to be a few issues in here, all mixed up together which is stopping
> me thinking straight about any individual one.  Let's try and enumerate them:
>
> 1) Project builds. After changing AspectProjectOne, we see it rebuild, but why
> does AspectProjectTwo rebuild?
> 
> 2) Classpath. Why is the AspectContainer/bin folder on the AspectProjectOne
> classpath multiple times.  Can we limit the number of times it is there, or
> improve AjState so it avoids repeating analysis for the same element twice.
> 
> 3) Periodic save.  Why does the periodic save thread continue to persist, only
> disappearing after a 'couple of minutes' (with periodic save set to 1min). 
> What does it mean for the periodic save thread to be asleep rather than not
> running - is it waiting for 1min of quiet before saving?
> 
> 4) Cyclic dependencies. Should the mixing up of aspectpath/inpath between two
> projects be reported as a cyclic dependency problem between two projects
> 
> 5) Refreshes ok?  If it is a cyclic dependency, why do we not see infinite
> rebuilds all the time for the AspectContainer and AspectProjectOne projects? 
> Is the refresh logic in AJDT AJBuilder incorrect?
> 
> 6) Inpath enhancement.  Can we improve the analysis of inpath elements to
> determine if they require us to build, rather than just looking at the
> timestamp.
> 
> 7) Diagnostics.  What diagnostics can we add to AJDT event trace to make any of
> 1-6 more clear...

This is an excellent breakdown and certainly will help with clarity in discussion.

The reason why I created this test case to begin with is either issue 5, or closely tied to issue 5.  You noted it in your annotated trace: "Another minute later, another build of AspectProjectOne - same as before, not clear to me why it didn't think the build was ok previously."

This is what I considered to be the heart of the bug.  All the other issues which have come to light in my test case are side effects of my attempts to re-create this mysterious rebuilding.  When this bug cropped up in our large project the building would continue without ceasing (infinite loop of builds...).

Jason
Comment 31 Andrew Clement CLA 2008-04-09 19:49:25 EDT
Problem (2) resolved.  Only analyse path entries once - at least that reduces
the output a bit, less to look through.  From AspectContainer build output:

12:34:17 Project=AspectContainer, kind of build requested=Incremental AspectJ
compilation
12:34:17 Classpath=...
12:34:17 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectOne\bin
12:34:17 Change detected in
C:\temp\TestCaseFolders\AspectProjectOne\bin\testing\one\AspectTargetOne.class
but it is not structural
12:34:17 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectTwo\bin
12:34:17 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectOne\bin
12:34:17 Change detected in
C:\temp\TestCaseFolders\AspectProjectOne\bin\testing\one\AspectTargetOne.class
but it is not structural
12:34:17 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectTwo\bin
12:34:17 Preparing for build: planning to be an incremental build

to

16:22:11 Project=AspectContainer, kind of build requested=Incremental AspectJ
compilation
16:22:11 Classpath=...
16:22:11 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectOne\bin
16:22:11 Change detected in
C:\temp\TestCaseFolders\AspectProjectOne\bin\testing\one\AspectTargetOne.class
but it is not structural
16:22:11 Found state instance managing output location :
C:\temp\TestCaseFolders\AspectProjectTwo\bin
16:22:11 Change detected in
C:\temp\TestCaseFolders\AspectProjectTwo\bin\testing\two\AspectTargetTwo.class
but it is not structural
16:22:11 Preparing for build: planning to be an incremental build

that change is committed in AspectJ, not yet committed in AJDT.
Comment 32 Andrew Clement CLA 2008-04-09 20:30:32 EDT
Project refresh in AJDT is done as follows:

After a build, if the project has a java project dependent, do a full refresh of everything in the project.  If the project only has AJDT project dependents, just refresh the output folders for the project.  i still have no idea what periodic save is expecting to happen.
Comment 33 Andrew Eisenberg CLA 2010-09-01 18:28:58 EDT
Anything left to do here?
Comment 34 Jason Naylor CLA 2010-09-02 10:57:07 EDT
Unfortunately we had to move away from the ajdt, so I can not verify if this bug is fixed.  As far as I am concerned if a periodic workspace save of eclipse with the test case results in a re-build then the bug still needs to be fixed, otherwise the problem is gone. Cheers!