Bug 212769 - SetClasspathOperation no longer adds project for refresh
Summary: SetClasspathOperation no longer adds project for refresh
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: 3.3.2   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-12-12 11:07 EST by Jason Peterson CLA
Modified: 2008-01-24 04:46 EST (History)
4 users (show)

See Also:
philippe_mulet: pmc_approved+


Attachments
Proposed fix and regression test (5.48 KB, patch)
2007-12-12 14:07 EST, Jerome Lanneluc CLA
no flags Details | Diff
Additional fix and new regression test (8.77 KB, patch)
2007-12-14 09:40 EST, Jerome Lanneluc CLA
no flags Details | Diff
Fix and regression tests for 3.3.2 (5.96 KB, patch)
2007-12-14 11:33 EST, Jerome Lanneluc CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Peterson CLA 2007-12-12 11:07:03 EST
Build ID:  I20071101-2000

The problem is that in JDT 3.2 when SetClasspathOperation was called the following line of code when called in the method executeOperation():

JavaModelManager.getJavaModelManager().getDeltaProcessor().addForRefresh(project);

This was important because after the SetClasspathOperation was done the following code was invoked in DeltaProcessor:

resourceChanged(IResourceChangeEvent event) {
.....
if (elementsToRefresh != null) {
   createExternalArchiveDelta(elementsToRefresh,null);
}
....

However, starting in JDT 3.3 the createExternalArchiveDelta is never called because elementsToRefresh is always null.  The reason being that no projects were called for refresh in the SetClasspathOperation.

The fix is to add the following line of code to the SetClassPathOperation.executeOperation():

JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(new IJavaElement[] {project}, null);

Note: the above line looks a little different then the line from 3.2 (due to JDT changes), but is doing the same thing as was being done in 3.2


More information:
This is a critical fix for us and has broken code that used to work fine in previous releases.  We not only need the fix in the new stream 3.4, but also in 3.3 since we have a beta product currently using the 3.3 stream.
Comment 1 Jerome Lanneluc CLA 2007-12-12 11:39:00 EST
Are you saying that you don't get a delta for external jars when modifying the raw classpath?
Is the classpath set by SetClasspathOperation different from the previous classpath?
Comment 2 Jason Peterson CLA 2007-12-12 12:09:06 EST
No, I do get a delta.  The classpath is changed and there is a delta.  DeltaProcessor is invoked, but the following code is never reached now in
JDT 3.3:

if (elementsToRefresh != null) {
   createExternalArchiveDelta(elementsToRefresh,null);
}

The problem is with elementsToRefresh.  This is always null now.  The following method in DeltaProcessState is never called now from the SetClasspathOperation

public synchronized void addForRefresh(IJavaElement externalElement) {
		if (this.externalElementsToRefresh == null) {
			this.externalElementsToRefresh = new HashSet();
		}
		this.externalElementsToRefresh.add(externalElement);
	} 

In JDT 3.2 this method was in DeltaProcessor instead of DeltaProcessorState.  That
is not the issue though.  The issue is that in 3.2 this method was invoked by the following line of code in SetClasspathOperation:  

JavaModelManager.getJavaModelManager().getDeltaProcessor().addForRefresh(project);


In JDT 3.3 this code is never invoked.  I added the following code to invoke it just as it was in 3.2 and it fixed the problem:

JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(new
IJavaElement[] {project}, null);

NOTE: refreshExternalArchives is the code in JDT 3.3 that calls the addForRefresh(IJavaElement externalElement)

Comment 3 Jerome Lanneluc CLA 2007-12-12 14:07:22 EST
Created attachment 85109 [details]
Proposed fix and regression test

Note the change is not in SetClasspathOperation has this needs to work also if the .classpath file is changed manually.

I will release the patch after more testing.
Comment 4 Bala Balakumran CLA 2007-12-13 10:00:01 EST
adding to the cc list to get notified when the patch is released.
Comment 5 Jason Peterson CLA 2007-12-14 01:20:36 EST
Thanks for the quick response.  I tried out the patch to test the refresh
issue.  The refresh is now working as it did in 3.2.  However, I am still getting class not found exceptions due to an invalid classpath.  I was on the right path with the refresh in the SetClasspathOperation, but the root of my problem is actually the fact that the following line is missing in the SetClasspathOperation.executeOperation():

project.updatePackageFragmentRoots(); 

NOTE: This line was right above the refresh for the 3.2 code.  

The issue is that our code is doing a setClasspath and soon after that
validation is being done on the type hierarchy for some classes in the project.
This is looked up by doing a IJavaProject.findType(String packageName, String typeQualifiedName)

This in turn gets the project's cache and passes the arg cache.allPkgFragmentRootsCache (first of 5 args) to NameLookup. However, without the project.updatePackageFragmentRoots() being called in SetClasspathOperation, cache.allPkgFragmentRootsCachehas not been updated yet and is missing all of my WAS Container jars.   
Comment 6 Jerome Lanneluc CLA 2007-12-14 09:40:42 EST
Created attachment 85276 [details]
Additional fix and new regression test
Comment 7 Jerome Lanneluc CLA 2007-12-14 11:33:20 EST
Created attachment 85292 [details]
Fix and regression tests for 3.3.2 

Note that the external jar delta problem is not present in 3.3.x. So only the project's cache problem is being backported. However the 2 tests are being backported.
Comment 8 Jerome Lanneluc CLA 2007-12-17 06:09:26 EST
Fixes and tests from comment 6 released for 3.4M5
Comment 9 Jerome Lanneluc CLA 2007-12-17 06:15:49 EST
We should backport the fix from comment 7 to 3.3.2 since:
- this is a regression comparing to 3.2
- clients that update their model by listening to Java deltas cannot work around the problem
- the fix is a one line change

Asking for PMC approval to backport to 3.3.2.
Comment 10 Philipe Mulet CLA 2007-12-17 10:42:02 EST
+1 for 3.3.2
Comment 11 Jerome Lanneluc CLA 2007-12-18 13:14:09 EST
Fix and tests from comment 7 released for 3.3.2
Comment 12 Eric Jodet CLA 2008-01-24 04:46:42 EST
Verified in the code for 3.3.2 using M20080123-0800 build