Bug 343584 - [ltk][reorg] Deleting physically nested projects can cause exceptions
Summary: [ltk][reorg] Deleting physically nested projects can cause exceptions
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.4.2+   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 245412
Blocks:
  Show dependency tree
 
Reported: 2011-04-21 12:41 EDT by Matthew Piggott CLA
Modified: 2011-08-25 03:26 EDT (History)
6 users (show)

See Also:
markus.kell.r: review+
sptaszkiewicz: review+
daniel_megert: review+


Attachments
Sort resources by location (1.45 KB, patch)
2011-04-21 13:46 EDT, Matthew Piggott CLA
no flags Details | Diff
Test case (642 bytes, application/octet-stream)
2011-05-04 12:11 EDT, Szymon Ptaszkiewicz CLA
no flags Details
Patch (2.69 KB, patch)
2011-06-03 12:56 EDT, Szymon Ptaszkiewicz CLA
no flags Details | Diff
Patch v2 (2.54 KB, patch)
2011-06-07 08:13 EDT, Szymon Ptaszkiewicz CLA
no flags Details | Diff
Patch v3 with tests (9.67 KB, patch)
2011-06-08 08:04 EDT, Markus Keller CLA
no flags Details | Diff
Patch v4 (7.42 KB, patch)
2011-06-08 10:57 EDT, Markus Keller CLA
daniel_megert: review+
Details | Diff
Patch v4 for R3_4_maintenance (2.11 KB, patch)
2011-06-09 10:59 EDT, Markus Keller CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Piggott CLA 2011-04-21 12:41:39 EDT
When deleting projects from the workspace and deleting the files on the disk if the parent is deleted before nested projects exceptions can be thrown:

org.eclipse.core.runtime.CoreException: Can not delete resource. Resource does not exist.
at org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange.perform(DeleteResourceChange.java:108)
at org.eclipse.ltk.core.refactoring.CompositeChange.perform(CompositeChange.java:278)
at org.eclipse.ltk.core.refactoring.CompositeChange.perform(CompositeChange.java:278)
at org.eclipse.ltk.core.refactoring.PerformChangeOperation$1.run(PerformChangeOperation.java:258)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2310)
at org.eclipse.ltk.core.refactoring.PerformChangeOperation.executeChange(PerformChangeOperation.java:306)
at org.eclipse.ltk.internal.ui.refactoring.UIPerformChangeOperation.executeChange(UIPerformChangeOperation.java:92)
at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:218)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2310)
at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Comment 1 Matthew Piggott CLA 2011-04-21 13:46:25 EDT
Created attachment 193866 [details]
Sort resources by location

I've attached a patch which sorts resources in reverse order so the deepest projects are deleted first.  However, there is also a problem that projects that are nested but were not selected for the delete operation are also removed from the disk.
Comment 2 Markus Keller CLA 2011-05-03 10:38:54 EDT
Nested project locations is an area that is not well-defined, see e.g. bug 245412.

We can fix this specific problem, but the fix should go into DeleteResourcesProcessor (probably into removeDescendants(..)). Also make sure you guard against getLocationURI() that return null and only do the comparisons for projects.
Comment 3 Szymon Ptaszkiewicz CLA 2011-05-04 12:11:59 EDT
Created attachment 194733 [details]
Test case

I think the problem described in comment 0 can be caused by inconsistencies in alias manager. Steps to reproduce:

1. Extract projects from the attached file into some location.
2. Import existing inner project "p2" (uncheck "Copy project into workspace").
3. Import existing outer project "p1" (uncheck "Copy project into workspace").
4. Select both projects and delete them in one operation.
=> You get exception as in comment 0.

Now try the same steps but first import the outer project "p1" and then the inner one => there will be no error. Deletion should not rely on the order in which projects were imported. I found that the problem is caused by AliasManager (after calling #updateAliases). If there are no other scenarios that can result in the same exception, then I think this should be moved to Platform/Resources to fix the problem in AliasManager.
Comment 4 Szymon Ptaszkiewicz CLA 2011-05-05 11:03:37 EDT
(In reply to comment #3)
> 4. Select both projects and delete them in one operation.

If you try to delete outer project "p1" only, then it works fine if the inner  project "p2" was imported as first. Strange thing -- deleting outer project "p1" after it was imported as first leaves project "p2" in workspace and leads to error during refresh. This should not happen. I will investigate that from the Resources perspective.
Comment 5 Szymon Ptaszkiewicz CLA 2011-05-05 11:23:37 EDT
(In reply to comment #4)
> Strange thing -- deleting outer project "p1" after it was imported as first 
> leaves project "p2" in workspace and leads to error during refresh. This should
> not happen.

This does not happen if you restart your Eclipse before deleting the project.
Comment 6 Szymon Ptaszkiewicz CLA 2011-05-30 06:40:09 EDT
Filed bug 347613 to handle problem described in comment 4.
Comment 7 Szymon Ptaszkiewicz CLA 2011-06-03 12:56:02 EDT
Created attachment 197318 [details]
Patch
Comment 8 Szymon Ptaszkiewicz CLA 2011-06-03 13:00:32 EDT
Markus, please review.
Comment 9 Markus Keller CLA 2011-06-06 14:48:06 EDT
(In reply to comment #7)
> Created attachment 197318 [details] [diff]
> Patch

With this patch, I can't delete sibling projects "p" and "p2" any more (e.g. both in the normal workspace location). I guess the best solution is to avoid doing manual string comparisons but rather use tests like this:

    if (otherURI.relativize(currURI) != currURI) ...
Comment 10 Szymon Ptaszkiewicz CLA 2011-06-07 05:03:16 EDT
(In reply to comment #9)
> (In reply to comment #7)
> > Created attachment 197318 [details] [details] [diff]
> > Patch
> 
> With this patch, I can't delete sibling projects "p" and "p2" any more (e.g.
> both in the normal workspace location). I guess the best solution is to avoid
> doing manual string comparisons but rather use tests like this:
> 
>     if (otherURI.relativize(currURI) != currURI) ...

Oops, my fault, I haven't thought about drawbacks of using #startsWith. I will correct the patch.
Comment 11 Szymon Ptaszkiewicz CLA 2011-06-07 08:13:58 EDT
Created attachment 197490 [details]
Patch v2
Comment 12 Matthew Piggott CLA 2011-06-07 09:46:07 EDT
Perhaps I'm missing something, but with the last patch won't the nested project be left in the workspace?
Comment 13 Szymon Ptaszkiewicz CLA 2011-06-08 06:00:48 EDT
(In reply to comment #12)
> Perhaps I'm missing something, but with the last patch won't the nested project
> be left in the workspace?

See comment 4 and comment 5. If you see the nested project left in the workspace, then you need to restart your Eclipse before deleting both projects the next time. This is needed to avoid a problem with alias manager.
Comment 14 Markus Keller CLA 2011-06-08 08:04:54 EDT
Created attachment 197587 [details]
Patch v3 with tests

Added tests, removed unnecessary parentheses, and replaced the ! URI#equals(..) test by !=.
Comment 15 Szymon Ptaszkiewicz CLA 2011-06-08 08:46:40 EDT
(In reply to comment #14)
> Created attachment 197587 [details]
> Patch v3 with tests
> 
> Added tests, removed unnecessary parentheses, and replaced the ! URI#equals(..)
> test by !=.

Is it safe to use != here?
Comment 16 Markus Keller CLA 2011-06-08 09:25:48 EDT
(In reply to comment #15)
> Is it safe to use != here?

Yes. The Javadoc of URI#relativize(URI) says "the given URI is returned". All known implementations adhere to this.

SzymonP, can you please confirm that the code in Patch v3 solves the problem in your use case?
Comment 17 Markus Keller CLA 2011-06-08 10:36:34 EDT
Patch v3 is also not good, since it doesn't remove the nested project when "Delete project contents on disk" is unchecked.
Comment 18 Markus Keller CLA 2011-06-08 10:57:33 EDT
Created attachment 197611 [details]
Patch v4

This fix also keeps the right preview and projects count in the Delete dialog. Added another test for comment 17.
Comment 19 Markus Keller CLA 2011-06-08 11:00:40 EDT
SzymonP, please check Patch v4.

The patch also applies to R3_4_maintenance (with fuzz factor 1).
We won't backport the test.
Comment 20 Szymon Ptaszkiewicz CLA 2011-06-09 05:56:30 EDT
(In reply to comment #19)
> SzymonP, please check Patch v4.
> 
> The patch also applies to R3_4_maintenance (with fuzz factor 1).
> We won't backport the test.

Patch v4 works nicely and solves my use case.
Comment 21 Markus Keller CLA 2011-06-09 10:59:22 EDT
Created attachment 197698 [details]
Patch v4 for R3_4_maintenance
Comment 22 Markus Keller CLA 2011-06-09 12:54:28 EDT
Released to the org.eclipse.ltk.core.refactoring branches R3_4_maintenance, R3_5_maintenance (new branch), R3_6_maintenance, and HEAD.
Increased plug-in versions and released the map files.

Opened bug 348930 to backport to R3_7_maintenance.
Comment 23 Dani Megert CLA 2011-08-25 03:26:02 EDT
Verified in M20110824-0800 on Linux.