Bug 97998 - [builder] improve the error handling in case the build encounters a locked file within the the output folder
Summary: [builder] improve the error handling in case the build encounters a locked fi...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 trivial (vote)
Target Milestone: 3.4 M1   Edit
Assignee: Maxime Daniel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-01 16:57 EDT by Stefan Xenos CLA
Modified: 2007-08-03 11:47 EDT (History)
1 user (show)

See Also:


Attachments
Experimental fix plus test case (5.99 KB, patch)
2007-06-06 10:13 EDT, Maxime Daniel CLA
no flags Details | Diff
What about this instead ? (4.79 KB, patch)
2007-06-28 14:58 EDT, Kent Johnson CLA
no flags Details | Diff
Fix + test case (7.91 KB, patch)
2007-07-11 04:52 EDT, Maxime Daniel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Xenos CLA 2005-06-01 16:57:42 EDT
If Eclipse detects that a file is locked during a build, it writes something
similar to the following to the log. This is a normal condition, not a bug in
Eclipse. As such, reporting it to the user in a problem marker is sufficient. It
should not be logged.

!MESSAGE Could not delete: /org.eclipse.ui.ide/bin/org.
!STACK 1
org.eclipse.core.internal.resources.ResourceException: Problems encountered
while deleting resources.
	at
org.eclipse.core.internal.localstore.FileSystemResourceManager.delete(FileSystemResourceManager.java:182)
	at
org.eclipse.core.internal.resources.ResourceTree.standardDeleteFolder(ResourceTree.java:614)
	at
org.eclipse.core.internal.resources.Resource.unprotectedDelete(Resource.java:1553)
	at org.eclipse.core.internal.resources.Resource.delete(Resource.java:664)
	at
org.eclipse.jdt.internal.core.builder.BatchImageBuilder.cleanOutputFolders(BatchImageBuilder.java:126)
	at
org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:36)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:216)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:148)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:593)
	at
org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1038)
	at org.eclipse.core.runtime.Platform.run(Platform.java:775)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:168)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:202)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:231)
	at
org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1038)
	at org.eclipse.core.runtime.Platform.run(Platform.java:775)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:234)
	at
org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:253)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:282)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:139)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:200)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:67)
Comment 1 Maxime Daniel CLA 2006-11-27 07:34:24 EST
I agree that the error showing up in the log is somewhat unfortunate. At the moment being, though, the error message in the interface is far from being perfect as far as helping the user to fix his error in concerned (merely tells that a class file was not written - not even saying which), while the log neatly tells which file failed and why.
I will then retitle this bug as '[builder] improve the error handling in case the build encounters a locked file within the the output folder' and I would attempt to improve the error message before cleansing the log.
Comment 2 Maxime Daniel CLA 2007-05-30 00:50:47 EDT
Reconsidering...

In fact, the error log only tells us who fails to delete, not what could not be deleted. Will investigate doing better here.

Reproducing the case needs some talent under Windows/NTFS, because marking a directory as read only does not prevent anyone from deleting its subparts (nor from creating subparts in it either). One way of doing the trick is to create a read-only directory and to install a non-empty, non-readable subdirectory in it. The attempt to delete the first directory then fails.
Under Linux, simply create a non-empty, read-only directory.

Comment 3 Maxime Daniel CLA 2007-05-30 00:52:06 EDT
(Another way to reproduce the bug under Windows is to edit a text file in the to be deleted directory. This does not cope that well with our automated tests though.)
Comment 4 Maxime Daniel CLA 2007-06-06 04:41:16 EDT
(In reply to comment #2)
...
> In fact, the error log only tells us who fails to delete, not what could not be
> deleted.
Wrong, the log tells us what could not be deleted, /org.eclipse.ui.ide/bin/org in this instance. Hence the log is precise enough.
Comment 5 Maxime Daniel CLA 2007-06-06 05:06:46 EDT
Taking a closer look at why we log this, it appears to me that we (JDT build) tend to log all filesystem related errors that have reasonable chances to happen because of conditions that are out of the control of Eclipse. While there exist means for the user to create the condition that generates the error above from within Eclipse (at least under Linux: proceed to the Resource perspective and change a non-empty output folder to read-only), those means are somewhat convoluted (need to get out of the Java perspective for the scenario I spell out above), and there is no easy quick-fix implemented. It is more probable that the problems arise from the use of external tools. I would contend that this apparent weakness comes from the fact that Eclipse does not take definite ownership of the underlying filesystem areas, and cannot control the exclusive access to it via itself.
All in all, we would then maintain the log.

There may remain an issue with the message itself.
Comment 6 Maxime Daniel CLA 2007-06-06 05:36:14 EDT
There is one case for which we get an imprecise message: doing a clean without an immediate build when the output folder is read-only. In cases where a build really happens (not clean only), the message includes the name of the precise resource that could not be deleted.
The behavior in case of a build is that the first file that cannot get deleted is reported (the choice is somewhat arbitrary). This has a drawback: the cause may be attached to another entry in the file system, aka the parent directory. But this has an advantage over only telling the user that something could not be deleted in the project, in that it gives a pointer to a precise file that got affected.
Accordingly, I'll attempt to get the same behavior (message with file picked up randomly amongst files that could not be deleted) for the clean only scenario.
Comment 7 Maxime Daniel CLA 2007-06-06 09:59:12 EDT
We have two places where we call getLocalizedMessage upon a CoreException instead of an ImageBuilderInternalException. The latter takes care of fetching the first child in case of a multi-status, which the former does not do.
Experimenting a patch that delegates the elaboration of the error message to a dedicated method instead of calling CoreException#getLocalizedMessage straight away.
Comment 8 Maxime Daniel CLA 2007-06-06 10:13:09 EDT
Created attachment 70327 [details]
Experimental fix plus test case
Comment 9 Maxime Daniel CLA 2007-06-11 05:44:15 EDT
Tests pass.
Kent, would you please tell me what you think, especially re. where we should put the exception formatting code?
Comment 10 Kent Johnson CLA 2007-06-28 14:58:10 EDT
Created attachment 72726 [details]
What about this instead ?

My preference would be to put it in the JavaBuilder & remove getLocalizedMessage() from ImageBuilderInternalException.

Its only sent from the JavaBuilder when we're building markers so it would make more sense to include it there.

We could replace the 3 references to Messages.build_inconsistentProject with a single call to a helper method that took the exception.
Comment 11 Maxime Daniel CLA 2007-07-11 04:24:51 EDT
Looks good. Will combine patches and release when tests complete.
Comment 12 Maxime Daniel CLA 2007-07-11 04:52:05 EDT
Created attachment 73518 [details]
Fix + test case

This patch combines Kent's for the code with mine for the test, further tuned to pass ErrorsTests under Linux (the added test won't cope with Windozes as is - JDK 6 has APIs that would allow this, but we cannot use it). Other tests currently running.
Comment 13 Maxime Daniel CLA 2007-07-11 05:13:24 EDT
Released for 3.4 M1.
Comment 14 Frederic Fusier CLA 2007-08-03 11:47:12 EDT
Verified for 3.4M1 using build I20070802-0800.