Bug 166580 - Multiple Output Paths trigger Full Rebuild Always
Summary: Multiple Output Paths trigger Full Rebuild Always
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Build (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.4   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-01 19:32 EST by Daniel Tabuenca CLA
Modified: 2007-10-10 10:22 EDT (History)
0 users

See Also:


Attachments
A JAR file containing a simple sample project to recreate the problem (2.89 KB, application/octet-stream)
2006-12-18 12:15 EST, Steve Young CLA
no flags Details
update harness to be able to specify if care about the order of the stderr output (2.18 KB, application/x-zip-compressed)
2006-12-22 07:50 EST, Helen Beeken CLA
no flags Details
zip containing tests and fixes (18.89 KB, application/x-zip-compressed)
2006-12-22 08:15 EST, Helen Beeken CLA
no flags Details
Replacement testcase class (15.20 KB, text/plain)
2006-12-22 09:10 EST, Helen Beeken CLA
no flags Details
test files that were missing from the previous patches (296 bytes, application/x-zip-compressed)
2007-01-02 06:50 EST, Helen Beeken CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Tabuenca CLA 2006-12-01 19:32:21 EST
Build ID: M20060921-0945

Steps To Reproduce:
1.Create a project with multiple output paths
2. Full Build
3. Modify any file
4. Incremental Build get's converted into Full Build 


More information:
When using Maven2 and generating an eclipse porject, the default is to generate a separate output path for unit test-classes than normal application classes. So Eclipse compiles test-classes to target/test-classe rather than target/classes.


What happens is when any file is changed and an incremental build triggered, ASPECTJ checks for changes in the classpath.... In so doing, it performs the following test inside AjState.changed(List oldPath, List newPath, boolean checkClassFiles, File oldOutputLocation):

if (f.exists() && f.isDirectory() && checkClassFiles && !(f.equals(oldOutputLocation)))

if this expression evaluates to true, it triggers cancels the incremental build and triggers a full build. When checking the folder /target/test-classes it checks to see if it matches the oldOutputLocation variable which  for some reason contains /target/classes (the default output folder). Thus, every time anything is changed, no matter where it triggers a full rebuild.

For the record, my test classes are not in my aspectj inpath and I don't use aspectj at all for my test classes.
Comment 1 Steve Young CLA 2006-12-18 12:15:22 EST
Created attachment 55861 [details]
A JAR file containing a simple sample project to recreate the problem
Comment 2 Steve Young CLA 2006-12-18 12:17:14 EST
After discussions with Helen and Andy, and running some tests, the consensus seems to be that this is an AspectJ bug.  AjState only stores one outpath, which is always set to the project default, regardless of whether the default is actually used.  Thus it is possible to have, say, a "src" folder with a corresponding "src_output" folder, a "tests" folder with a corresponding "tests_output" folder, and a redundant project default output folder set to something else completely, yet the later is always used for comparisons by AjState.
Comment 3 Steve Young CLA 2006-12-18 12:22:38 EST
Over to the AspectJ folks...
Comment 4 Helen Beeken CLA 2006-12-21 12:43:40 EST
Looking into the AjState and incremental building, there's a whole host of things which do not cope with having multiple output directories. I believe I've fixed these and in doing so also fixed this bug, however, I'm finding it hard to write a MultiProjectIncrementalTest which fails in the same way that I see in a runtime workbench. I think this is merely down to differences between the harness and how ajdt uses ajde. However, I have tested my fix in a runtime workbench and am no longer seeing full builds when they should be incremental. I'll keep going with trying to write a test for this bug....
Comment 5 Helen Beeken CLA 2006-12-22 03:43:51 EST
The reason I wasn't able to reproduce this within the test harness was that AJDT includes all output directories on its classpath whereas our harness didn't. Fixing that means I now have a testcase.
Comment 6 Helen Beeken CLA 2006-12-22 07:50:31 EST
Created attachment 56092 [details]
update harness to be able to specify if care about the order of the stderr output

The changes that I've made mean that we can no longer count on the order that aspects appear in the aop.xml file (because I'm having to record the filename the aspect is in along with the name of the aspect I'm using a HashMap which doesn't guarentee order). There's one LTW test (LTWTests.testAspectsIncludeWithLintWarning) that fails because of this. After discussions with Matthew, this particular test just cares that the messages come out rather than in which order, therefore I've modified the harness to take an extra argument as to whether or not we care about the order. The xml can now be:

<run class="Main" ltw="aop-aspectsincludewithlintwarning.xml">
   <stdout>
      <line text="Main.main"/>
      <line text="Main.test1"/>
      <line text="Main.test2"/>
   </stdout>
   <stderr ordered="no">    <--------------- added option
      <line text="warning aspect Aspect1 exluded for class loader org.aspectj.weaver.loadtime.WeavingURLClassLoader [Xlint:aspectExcludedByConfiguration]"/>
      <line text="warning aspect Aspect2 exluded for class loader org.aspectj.weaver.loadtime.WeavingURLClassLoader [Xlint:aspectExcludedByConfiguration]"/>
      <line text="pakkage.Aspect3.before_test2"/>
    </stderr>
</run>


The attached zip file contains two patches:

- testing.txt : apply to the testing project
- tests.txt: apply to the tests project

These patches provide the changes to the test harness.
Comment 7 Helen Beeken CLA 2006-12-22 08:15:29 EST
Created attachment 56094 [details]
zip containing tests and fixes

The attached zip contains the following:

- ajde.txt: apply this patch to the ajde project
- ajdt-core.txt: apply this patch to the org.aspectj.ajdt.core project
- testing.txt: apply this patch to the testing project (this patch is a duplicate of the patch provided in comment #6)
- tests.txt: apply this patch to the tests project (this patch contains the patch provided in comment #6 but adds a lot more tests for this bug)
- inpathJar.jar - place in tests\multiIncremental\inpathTesting\base


To test these patches and ensure that the tests fail before applying the fixes you need to apply the ajde.txt patch. This adds a couple of extra interface methods to OutputLocationManager. You also need to apply the part of ajdt-core.txt to CompilationResultDestinationManager (this adds the same two interface methods). Not doing this means that not all the output locations are added to the classpath in AjdeInteractionTestbed.MyProjectPropertiesAdapter. Consequently the test IncrementalOutputLocationManagerTests.testPr166580() will pass without my fixes (this was the reason it was failing in AJDT and I initially had trouble reproducing it in the harness).

Together these patches provide testcases and fixes for all the places AjBuildConfig.getOutputDir() was called without taking into account that this may return null or that there may be an outputLocationManager.
Comment 8 Helen Beeken CLA 2006-12-22 09:10:00 EST
Created attachment 56095 [details]
Replacement testcase class

Replace the version of MoreOutputLocationManagerTests in the patch provided with the previous comment with this one. This version uses the correct outputlocationmanager (although there's no difference in impls, this one was meant to be used instead)
Comment 9 Andrew Clement CLA 2006-12-22 12:44:19 EST
mmm, i applied all the patches then ran the tests, this test failed for me:

testAjStateDeleteResourcesInInputDir

failed with:
junit.framework.AssertionFailedError: expected state to have resource inDirResource.txtbut it did not
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.Assert.assertTrue(Assert.java:20)
	at org.aspectj.systemtest.incremental.tools.MoreOutputLocationManagerTests.testAjStateDeleteResourcesInInputDir(MoreOutputLocationManagerTests.java:264)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

what did i do wrong?
Comment 10 Helen Beeken CLA 2007-01-02 06:50:43 EST
Created attachment 56280 [details]
test files that were missing from the previous patches

Oooops - yes, the previous attachments did not contain the text files needed for this test. This attachment contains the two missing resources:

- inDirResource.txt - copy to tests\multiIncremental\inpathTesting\base\injarBin\pkg

- inpathResource.txt - copy to tests\multiIncremental\inpathTesting\origInpathClass
Comment 11 Andrew Clement CLA 2007-01-09 04:45:32 EST
tests now pass. patches in.
iplog
Comment 12 Helen Beeken CLA 2007-01-10 08:08:28 EST
This fix is now available in AJDT 1.5.0.200701100718 for Eclipse 3.3M4 .
Comment 13 Andrew Clement CLA 2007-01-29 05:59:47 EST
fix available in latest AJ builds too.