Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 244315 - IllegalArgumentException from IFolder#refreshLocal
Summary: IllegalArgumentException from IFolder#refreshLocal
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Resources (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal with 3 votes (vote)
Target Milestone: 4.2.1   Edit
Assignee: John Arthorne CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 144610 367669
  Show dependency tree
 
Reported: 2008-08-15 12:04 EDT by Igor Fedorenko CLA
Modified: 2012-09-11 09:22 EDT (History)
8 users (show)

See Also:


Attachments
unit test that demostrates the problem (5.89 KB, application/zip)
2008-08-15 12:04 EDT, Igor Fedorenko CLA
no flags Details
Fix and regression test (4.41 KB, patch)
2012-05-22 15:44 EDT, John Arthorne CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Igor Fedorenko CLA 2008-08-15 12:04:37 EDT
Created attachment 110100 [details]
unit test that demostrates the problem

When mapping Maven projects into Eclipse workspace, m2e creates project structure that looks something like that

parent
  /moduleA

moduleA

Where moduleA is located at the same local filesystem path as parent/moduleA. (as a side note, there can be more than one module project and modules can be nested inside modules).

Although infrequently, we are getting IllegalArgumentException as below when refreshing subfolders of the module projects. The problem happens on eclipse 3.3.2 and 3.4.0, but eclipse 3.2.2 seems to work properly.


java.lang.IllegalArgumentException: Element not found: /parent/module/target.
	at org.eclipse.core.internal.watson.ElementTree.elementNotFound(ElementTree.java:255)
	at org.eclipse.core.internal.watson.ElementTree.createElement(ElementTree.java:183)
	at org.eclipse.core.internal.resources.Workspace.createResource(Workspace.java:857)
	at org.eclipse.core.internal.resources.Workspace.createResource(Workspace.java:814)
	at org.eclipse.core.internal.localstore.RefreshLocalVisitor.createResource(RefreshLocalVisitor.java:82)
	at org.eclipse.core.internal.localstore.RefreshLocalAliasVisitor.createResource(RefreshLocalAliasVisitor.java:37)
	at org.eclipse.core.internal.localstore.RefreshLocalVisitor.synchronizeExistence(RefreshLocalVisitor.java:218)
	at org.eclipse.core.internal.localstore.RefreshLocalVisitor.visit(RefreshLocalVisitor.java:290)
	at org.eclipse.core.internal.localstore.UnifiedTree.accept(UnifiedTree.java:99)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refreshResource(FileSystemResourceManager.java:733)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refresh(FileSystemResourceManager.java:717)
	at org.eclipse.core.internal.resources.Resource.refreshLocal(Resource.java:1420)
	at alias.AliasTest$2.run(AliasTest.java:77)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1797)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1779)
	at alias.AliasTest.testAlias(AliasTest.java:62)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at junit.framework.TestCase.runTest(TestCase.java:164)
	at junit.framework.TestCase.runBare(TestCase.java:130)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:120)
	at junit.framework.TestSuite.runTest(TestSuite.java:230)
	at junit.framework.TestSuite.run(TestSuite.java:225)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
	at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethod(EclipseAppContainer.java:572)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:171)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1173)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1148)
Comment 1 Fred Bricon CLA 2011-07-15 18:16:38 EDT
I'm still seeing the problem occasionally with Eclipse 3.7.
Comment 2 Szymon Brandys CLA 2012-02-29 06:18:41 EST
(In reply to comment #1)
> I'm still seeing the problem occasionally with Eclipse 3.7.

Could you provide reproducible steps? Maybe you have a workspace that fails on refresh? You could attach it, even if it happens occasionally.
Comment 3 Markus Keller CLA 2012-02-29 06:26:38 EST
Bug 367669 has a few tests that fail from time to time. Note that we've only seen these on Linux and Mac so far, but not on Windows. Could be a coincidence, though.

- FatJarExportTests in org.eclipse.jdt.ui.tests
- AttachSourceTests in org.eclipse.jdt.core.tests.model
Comment 4 Jay Arthanareeswaran CLA 2012-04-12 03:47:23 EDT
In the case of bug 367669, what we are trying to do is create a new link folder in the external folders project, which JDT uses to keep track of external folders. Looking at the stack trace, it's hard to tell what exactly went wrong because in ElementTree#createElement, we do not log the information from the original ObjectNotFoundException. Can this be done for M7, which will help the investigation?

For bug 367669, just by going through the code, I think the issue could be because of the parent folder, which happens to be the external folders project root itself, not being found among the nodes - DeltaDataTree, line: 72. Can someone from the resources team confirm if this analysis is correct and help me with further hints if any? TIA
Comment 5 John Arthorne CLA 2012-04-12 09:14:14 EDT
I don't think logging the ObjectNotFoundException will tell you anything new. This exception means we are trying to add a child where the parent does not exist. The Illegal arg exception already tells us the parent path that is missing: "/parent/module/target".

The strange thing is, this is happening during a refresh local traversal, where we are doing a breadth-first traversal of the resource tree to make it consistent with the current file system. So we should have just visited the parent node and made sure it was in sync with the file system immediately before visiting this child. This means we have a case where we think the parent does not exist on disk (so we removed it), but the child *does* exist on disk. If we had steps to reproduce I'm sure we could sort this out very quickly.
Comment 6 Jay Arthanareeswaran CLA 2012-04-12 10:19:01 EDT
(In reply to comment #5)
> I don't think logging the ObjectNotFoundException will tell you anything new.
> This exception means we are trying to add a child where the parent does not
> exist. The Illegal arg exception already tells us the parent path that is
> missing: "/parent/module/target".
 
Well, I was hoping that there would be some other reason for that, because in bug 367669, we are trying to add the resource to the project root. It's very surprising in this case, because just before adding the resource to the project, we make sure that the project exists, if not we even create it.

At this point we can't reproduce the bug, but there are some tests that fail occasionally. I have inserted some trouble-shooting code in JDT/Core. Hopefully they will reveal something when the failure occurs again.
Comment 7 Markus Keller CLA 2012-04-12 15:04:03 EDT
It could also be a concurrency issue. Is the traversal guaranteed to only occur in one thread at a time?

The ExternalFoldersManager still has synchronization gaps, e.g. addFolder(..) reads and writes pendingFolders without synchronization. I wouldn't be too surprised if it tried to create/refresh the same folder concurrently.
Comment 8 Jay Arthanareeswaran CLA 2012-04-13 02:03:39 EDT
(In reply to comment #7)
> The ExternalFoldersManager still has synchronization gaps, e.g. addFolder(..)
> reads and writes pendingFolders without synchronization. I wouldn't be too
> surprised if it tried to create/refresh the same folder concurrently.

The pendingFolders is protected from concurrency by means of a synchronized Set already. Did I miss something there? And I can't imagine concurrency issues within a seemingly simple unit test. Besides, from what John is saying, the project folder itself seem to have disappeared.
Comment 9 Markus Keller CLA 2012-04-13 10:41:27 EDT
(In reply to comment #8)
I filed bug 376724 for the synchronization problems in ExternalFoldersManager.
Comment 10 Stephan Herrmann CLA 2012-04-29 06:01:59 EDT
(In reply to comment #5)
> The strange thing is, this is happening during a refresh local traversal, where
> we are doing a breadth-first traversal of the resource tree to make it
> consistent with the current file system. So we should have just visited the
> parent node and made sure it was in sync with the file system immediately
> before visiting this child. This means we have a case where we think the parent
> does not exist on disk (so we removed it), but the child *does* exist on disk.
> If we had steps to reproduce I'm sure we could sort this out very quickly.

If the parent is the external links project, and the child a linked external folder: if we delete the parent, what exactly are isAccessible() & isLinked() on the child checking? Existence of the link or existence of the link target?
If its the latter wouldn't this explain why the tree assumptions don't hold, why a child exists while its parent doesn't?

(see also bug 367669 comment 32)
Comment 11 John Arthorne CLA 2012-05-22 15:44:45 EDT
Created attachment 216072 [details]
Fix and regression test

Here is a fix, with a cleaned up version of Igor's original regression test. I clearly missed that there was a simple test case available when I made comment #5.

The root problem is that a resource is created within a nested project immediately after it was created.  Since AliasManager updates its list of overlapping resources based on resource change events, it hasn't done this at the time the folder is created. Therefore we are in a state where the aliases of the folder have not yet been created in the resource tree.

Although the fix seems obvious to me now, I have a hard time justifying fixing this in RC2 given that it's been around for four years already.  I think this is most likely to happen in JUnit tests.
Comment 13 John Arthorne CLA 2012-09-11 09:22:51 EDT
Verified the regression test is running and passing in M20120909-2000.