Bug 124290 - AbstractImageBuilder writeClassFileBytes creates resources before calling setDerived
Summary: AbstractImageBuilder writeClassFileBytes creates resources before calling set...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M5   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 124322
Blocks:
  Show dependency tree
 
Reported: 2006-01-18 09:21 EST by Jeremy Sheeley CLA
Modified: 2006-02-14 08:52 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeremy Sheeley CLA 2006-01-18 09:21:03 EST
In the else clause of writeClassFileBytes:
// Default implementation just writes out the bytes for the new class file...
		if (JavaBuilder.DEBUG)
			System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$
		file.create(new ByteArrayInputStream(bytes), IResource.FORCE, null);
		file.setDerived(true);

create calls Workspace.endOperation(), which will sometimes (if the build takes long enough) call broadcastPostChange().  This means that a IResourceChangeListener listening to IResourceChangeEvent.POST_CHANGE events will have find one class file resource which is not marked derived.  This means that team providers who are listening to POST_CHANGE events to add non-derived resources, will accidentally add class files.

I propose that it should call setDerived(true) before calling create().
Comment 1 Jeremy Sheeley CLA 2006-01-18 09:22:29 EST
Also, any advice on a workaround for 3.0 and 3.1 would be appreciated.
Comment 2 Jerome Lanneluc CLA 2006-01-18 09:29:54 EST
I believe that calling setDerived(boolean) on an IFile that doesn't yet exist will throw a CoreException.
We might need a new API from Platform/Resources.
Comment 3 Kent Johnson CLA 2006-01-18 10:12:09 EST
John: are post change events postponed until the build finishes?
Comment 4 Philipe Mulet CLA 2006-01-18 11:29:53 EST
We would need an atomic derived file creation. Maybe we could nest both actions into a batch operation, but it feels overkill.
Comment 5 John Arthorne CLA 2006-01-18 11:34:01 EST
I agree you would need new API from core.  I will do this.
Comment 6 John Arthorne CLA 2006-01-18 15:52:36 EST
I have added new API from core.  You can now replace those two lines with:

file.create(new ByteArrayInputStream(bytes), IResource.FORCE|IResource.DERIVED, null);
Comment 7 Jeremy Sheeley CLA 2006-01-19 10:34:57 EST
Workaround for those who are developing 3.0 and 3.1 plugins and encounter this bug:

In your class that implements IResourceChangeListener, save all of the resources that are not marked derived in the delta.  Create a new Job and call

myJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(ResourcesPlugin.getWorkspace().getRoot()));

In the Job's run method, you can loop over the resources re-checking to see if they are still derived.  The rule will prevent the job from running until after the build is finished.

Comment 8 Kent Johnson CLA 2006-01-20 11:36:33 EST
John, do we also need a new API for:

folder.create(true, true, null);
folder.setDerived(true);

and

file.setContents(new ByteArrayInputStream(bytes), true, false, null);
if (!file.isDerived())
  file.setDerived(true);

and

resource.copy(copiedResource.getFullPath(), IResource.FORCE, null);
copiedResource.setDerived(true);
Comment 9 John Arthorne CLA 2006-01-20 11:47:11 EST
1) Already exists: IFolder.create(IResource.DERIVED, true, monitor)

2) I'm not sure when this case exists. Why wouldn't the file be derived already?  In any case, you can call setDerived(true) before setContents() to ensure the delta is correct in thise case.

3) There's no API for this, and I can see the need - I'll add that one.
Comment 10 John Arthorne CLA 2006-01-20 12:57:26 EST
I have implemented IResource#copy(IPath, IResource.DERIVED, monitor)
Comment 11 Kent Johnson CLA 2006-01-25 14:18:30 EST
Inlined senders of setDerived() where possible with new IResource.DERIVED flag.
Comment 12 David Audel CLA 2006-02-14 08:52:25 EST
Verified for 3.2 M5 using build I20060214-0010