Community
Participate
Working Groups
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().
Also, any advice on a workaround for 3.0 and 3.1 would be appreciated.
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.
John: are post change events postponed until the build finishes?
We would need an atomic derived file creation. Maybe we could nest both actions into a batch operation, but it feels overkill.
I agree you would need new API from core. I will do this.
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);
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.
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);
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.
I have implemented IResource#copy(IPath, IResource.DERIVED, monitor)
Inlined senders of setDerived() where possible with new IResource.DERIVED flag.
Verified for 3.2 M5 using build I20060214-0010