Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 364450 - Dubious class path error triggers a full rebuild
Summary: Dubious class path error triggers a full rebuild
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4.2   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.4.2+   Edit
Assignee: Ayushman Jain CLA
QA Contact:
URL:
Whiteboard: To be verified for 3.6.2+J7, 3.6.2+,3...
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-22 05:24 EST by Szymon Ptaszkiewicz CLA
Modified: 2015-10-16 18:53 EDT (History)
6 users (show)

See Also:
srikanth_sankaran: review+


Attachments
proposed fix v1.0 + regression tests (3.31 KB, patch)
2011-12-09 01:56 EST, Ayushman Jain CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Szymon Ptaszkiewicz CLA 2011-11-22 05:24:57 EST
The following test case should show two fatal errors regarding unresolved w.I. If we do some change e.g. change the type of w.W#i from w.I to I, and then undo this change, we will get two build path errors:

1. "The project was not built since its build path is incomplete. Cannot find the class file for w.I. Fix the build path then try building this project"

2. "The type w.I cannot be resolved. It is indirectly referenced from required .class files"

We can observe the same problem, if we change the order of imports in a.A instead of changing the type of w.W#i. After the clean correct errors are shows again.

----------%<-----------
package a;

import w.I;
import w.W;

public class A {
}

package w;

public class W {
	private w.I i;
}
----------%<-----------
Comment 1 Srikanth Sankaran CLA 2011-11-23 09:26:54 EST
This looks like a case of there being some instability in the error messages
reported in the full build case vs incremental build case.

Not clear, at least not patently clear, that either set of messages is 
misleading/incorrect.

I'll study this in more detail.
Comment 2 Ayushman Jain CLA 2011-12-01 02:19:01 EST
An easier way to reproduce - in A.java, press space and save -> error appears, again press space and save -> error disappears.
First impressions - this seems to happen because of a race condition between reconciler and the compiler.
The second "indirectly referenced from required .class files" error occurs when compiler finishes after reconciler. While when the reconciler finishes last, there is only 1 error. This is because the compiler tries to build the binary type binding for W, that was found in W.class, and finds an unresolved reference to w.I in the class file. On the other hand, the reconciler just gets the source type W.
Comment 3 Ayushman Jain CLA 2011-12-01 03:36:16 EST
Digging deeper it looks like reconciler behaves consistently. The problem is in fact in the resource deltas. In one case, the deltas correspond to both W.java and A.java. In this case W.java is resolved first and hence is available when A.java begins to resolve. In the other case, the deltas correspons to only A.java, and W is picked up from classfile. Don't know why the resource deltas behave differently every alternate time.
Comment 4 Ayushman Jain CLA 2011-12-01 05:34:36 EST
This is why behaviour differs every alternate time:
1. When we do a clean build all source files are build and thus there is no "indirect reference from .class file" error
2. The next time we modify and save A, only A is built (incremental build), and W is picked up from its class file. This causes the "indirect reference from .class file" error which is a build path error.
3. Once again when we modify and save A, the incremental java builder figures out there's a buildpath error since the last build, and goes back to building ALL sources, taking us back to 1.

So, I think we should avoid reporting the "indirectly referenced from .class files" error somehow.
Comment 5 John Mising name CLA 2011-12-06 21:32:47 EST
I would like to describe the impact of the issue that users are experiencing.
This improper build path error makes the Java builder runs as full build whenever there is a change in any sources that belong to the project. Therefore it results in build performance degradation.
Comment 6 Srikanth Sankaran CLA 2011-12-06 22:40:55 EST
Ayush, please follow up just as soon as M4 is cooked and shipped.
Thanks for marking me for review.
Comment 7 Ayushman Jain CLA 2011-12-07 00:43:44 EST
(In reply to comment #5)
> I would like to describe the impact of the issue that users are experiencing.
> This improper build path error makes the Java builder runs as full build
> whenever there is a change in any sources that belong to the project. Therefore
> it results in build performance degradation.

I understand the problem. We've been focusing on shipping M4 this week so I couldn't get much time on this. I will follow up on my analysis soon.
Comment 8 Ayushman Jain CLA 2011-12-09 01:56:50 EST
Created attachment 208136 [details]
proposed fix v1.0 + regression tests

This is what happens in A.java after typing a space and saving (after a full build):
1. Import w.I is found to be bogus and I is put in the cache as a not found type.
2. Import w.W is found and compiler starts to resolve W from the already compiled W.class file.
3. The compiler finds a missing w.I again in W.class and goes to org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getTypeFromCompoundName(char[][], boolean, boolean). Here, it looks into the cache and finds a not found type, thereby eliciting a classpath error.
However, this is not needed because if the type was already in the cache as a not found type, we've already complained against it. This is where the patch helps.
Comment 9 Ayushman Jain CLA 2011-12-09 02:06:21 EST
The following strategies were considered and rejected, in consultation with Satyam:
1. To not generate a .class file for W since it has an unresolved type error. However, this will make the incremental builds really slow since there will be more CU's to process.
2. To have the compiler's NameEnvironment always use sources when sources are available instead of using .class files, just like the reconciler's SearchableEnvironment. However => again performance hit since resolving binary classes is faster.

The current patch seems like the best solution and passes all tests.
Srikanth, please review, its a one line change. Thanks!
Comment 10 Srikanth Sankaran CLA 2011-12-13 07:31:59 EST
Brought about by https://bugs.eclipse.org/bugs/show_bug.cgi?id=196200.
Comment 11 Srikanth Sankaran CLA 2011-12-13 08:39:08 EST
Fix and tests look good. Basically, a class path error is indicated
when we are unable to locate some type now, which we could locate 
properly earlier while building some other piece (a binary class file).
That is not the case here.

Thanks for the quick resolution, Ayush.

Dani, this is reported against 3.4.2, what streams should we release it
in ourselves and for what streams a source patch is enough ? 

(It is a one-line fix btw)
Comment 12 Ayushman Jain CLA 2011-12-14 01:30:08 EST
Released in master via commit b78c9eb519121b68605325fd214ba23170967998.

Released in maintenance via commit 626c55af72d40b07c0ba5d8332f9d48da304abca.
Comment 13 Dani Megert CLA 2011-12-14 02:34:56 EST
(In reply to comment #11)
> Fix and tests look good. Basically, a class path error is indicated
> when we are unable to locate some type now, which we could locate 
> properly earlier while building some other piece (a binary class file).
> That is not the case here.
> 
> Thanks for the quick resolution, Ayush.
> 
> Dani, this is reported against 3.4.2, what streams should we release it
> in ourselves and for what streams a source patch is enough ? 

All branches >= R3_4_maintenance including R3_6_maintenance_Java7.
Comment 15 Ayushman Jain CLA 2011-12-14 06:44:27 EST
Released in R3_6_maintenance branch via commit c251eb3f1fc1878627fdc704bb1636e70f3db615
Comment 16 Ayushman Jain CLA 2011-12-14 06:52:05 EST
Released in R3_5_maintenance branch via commit b00a5c1a34864630f0714dfada5ae77cda61169d
Comment 17 Ayushman Jain CLA 2011-12-14 08:12:30 EST
(In reply to comment #16)
> Released in R3_5_maintenance branch via commit
> b00a5c1a34864630f0714dfada5ae77cda61169d

Released into R3_5_maintenance CVS branch.
Comment 18 Ayushman Jain CLA 2011-12-14 15:06:26 EST
Released in R3_4_maintenance(CVS).
Comment 19 Ayushman Jain CLA 2011-12-14 15:08:03 EST
Phew!
Comment 20 Srikanth Sankaran CLA 2012-01-19 01:48:05 EST
Verified for 3.7.2RC2 using build M20120118-0800
Comment 21 Satyam Kandula CLA 2012-01-23 08:47:28 EST
Verified for 3.8M5 using build I20120122-2000
Comment 22 Eclipse Genie CLA 2015-10-16 04:30:21 EDT
New Gerrit change created: https://git.eclipse.org/r/58301