Bug 238179 - API to disallow workspace modification during JDT/Core operations
Summary: API to disallow workspace modification during JDT/Core operations
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2.1   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-06-23 17:21 EDT by Grant Taylor CLA
Modified: 2008-12-01 11:54 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Grant Taylor CLA 2008-06-23 17:21:11 EDT
Build ID: org.eclipse.jdt_3.2.1.r321_v20060823.jar

Steps To Reproduce:
In our product, we make use of the JDT APIs.  In one case, we are simply trying to obtain some information about packages and source folders.  However, when making these seemingly read-only calls, JDT attempts to modify the workspace.  A hang results because the workspace is an exclusive use resource (of course).  The originating code is a decorator, making it difficult or undesirable to introduce a scheduling rule.


More information:
Comment 1 Jerome Lanneluc CLA 2008-06-24 05:27:43 EDT
Can you please be more specific? What API are you using? How do I reproduce the problem? Why is it critical? (see https://bugs.eclipse.org/bugs/page.cgi?id=fields.html#bug_severity where "critical" is defined as "crashes, loss of data, severe memory leak") Is it the case?
Comment 2 Jerome Lanneluc CLA 2008-06-24 05:29:50 EDT
Also when you say "hang" do you mean a deadlock? See http://wiki.eclipse.org/index.php/How_to_report_a_deadlock
Comment 3 Philipe Mulet CLA 2008-06-24 07:39:33 EDT
Is this issue really critical ? If so, should it be planned for 3.4.1 or 3.5 ?
If not, please lower its severity
Comment 4 Grant Taylor CLA 2008-06-24 17:24:45 EDT
I believe this is critical because it causes a deadlock in our product, possibly causing data loss.  The stack I put into the defect shows our entry point into the JDT code.  Earlier on in the stack, a synchronized piece of code is being executed, which is why another thread (which holds the workspace lock) cannot proceed (hence the deadlock).
Comment 5 Jerome Lanneluc CLA 2008-06-25 01:57:08 EDT
(In reply to comment #4)
> The stack I put into the defect shows our entry
> point into the JDT code. 

What stack? There is no stack in this bug report.

Comment 6 Grant Taylor CLA 2008-06-25 08:44:51 EDT
Doh!!  You're absolutely right.  Here is the stack (with our product portion of it removed).

3XMTHREADINFO      "Worker-2" (TID:0x48234100, sys_thread_t:0x486502CC, state:CW, native ID:0x00000460) prio=5
4XESTACKTRACE          at java/lang/Object.wait(Native Method)
4XESTACKTRACE          at java/lang/Object.wait(Bytecode PC:3(Compiled Code))
4XESTACKTRACE          at org/eclipse/core/internal/jobs/ThreadJob.joinRun(Bytecode PC:273)
4XESTACKTRACE          at org/eclipse/core/internal/jobs/ImplicitJobs.begin(Bytecode PC:207)
4XESTACKTRACE          at org/eclipse/core/internal/jobs/JobManager.beginRule(Bytecode PC:16)
4XESTACKTRACE          at org/eclipse/core/internal/resources/WorkManager.checkIn(Bytecode PC:40)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.prepareOperation(Bytecode PC:34)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.run(Bytecode PC:37)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/DeltaProcessingState$ProjectUpdateInfo.updateProjectReferencesIfNecessary(Bytecode PC:137)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/DeltaProcessingState.updateProjectReferences(Bytecode PC:106)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/SetClasspathOperation.updateProjectReferencesIfNecessary(Bytecode PC:47)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/SetClasspathOperation.executeOperation(Bytecode PC:1)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelOperation.run(Bytecode PC:45)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.run(Bytecode PC:80)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelOperation.runOperation(Bytecode PC:50)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.setRawClasspath(Bytecode PC:43)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore$5.run(Bytecode PC:102)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/BatchOperation.executeOperation(Bytecode PC:10)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelOperation.run(Bytecode PC:45)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.run(Bytecode PC:80)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.run(Bytecode PC:42)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.setClasspathContainer(Bytecode PC:446)
4XESTACKTRACE          at org/eclipse/jdt/internal/launching/JREContainerInitializer.initialize(Bytecode PC:72)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.initializeContainer(Bytecode PC:175)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager$8.run(Bytecode PC:108)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.run(Bytecode PC:80)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.initializeAllContainers(Bytecode PC:321)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.getClasspathContainer(Bytecode PC:26)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.getClasspathContainer(Bytecode PC:7)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:242)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:203)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/DeltaProcessingState.initializeRoots(Bytecode PC:149)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelOperation.run(Bytecode PC:41)
4XESTACKTRACE          at org/eclipse/core/internal/resources/Workspace.run(Bytecode PC:80)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.run(Bytecode PC:42)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.setClasspathContainer(Bytecode PC:446)
4XESTACKTRACE          at org/eclipse/jdt/internal/launching/JREContainerInitializer.initialize(Bytecode PC:72)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.initializeContainer(Bytecode PC:175)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.getClasspathContainer(Bytecode PC:36)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.getClasspathContainer(Bytecode PC:7)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:242)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:203)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.setClasspathContainer(Bytecode PC:380)
4XESTACKTRACE          at org/eclipse/jst/j2ee/internal/common/classpath/J2EEComponentClasspathContainer.install(Bytecode PC:93)
4XESTACKTRACE          at org/eclipse/jst/j2ee/internal/common/classpath/J2EEComponentClasspathInitializer.initialize(Bytecode PC:2)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.initializeContainer(Bytecode PC:175)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaModelManager.getClasspathContainer(Bytecode PC:36)
4XESTACKTRACE          at org/eclipse/jdt/core/JavaCore.getClasspathContainer(Bytecode PC:7)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:242)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getResolvedClasspath(Bytecode PC:203)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.buildStructure(Bytecode PC:20)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/Openable.generateInfos(Bytecode PC:185)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaElement.openWhenClosed(Bytecode PC:21)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaElement.getElementInfo(Bytecode PC:22)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaElement.getElementInfo(Bytecode PC:2)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaElement.getChildren(Bytecode PC:1)
4XESTACKTRACE          at org/eclipse/jdt/internal/core/JavaProject.getPackageFragmentRoots(Bytecode PC:1)
Comment 7 Jerome Lanneluc CLA 2008-06-26 03:59:17 EDT
Could you please provide the name of the org.eclipse.jdt.core jar file as well?
Comment 8 Grant Taylor CLA 2008-06-26 09:31:20 EDT
I see this jar in our env:
org.eclipse.jdt.core_3.2.8.v_691_R32x.jar
Comment 9 Jerome Lanneluc CLA 2008-08-21 07:41:49 EDT
We would also need the other stack traces to understand the deadlock. Actually a full thread dump is needed. For now there is no proof that the deadlock is caused by us.
Comment 10 Grant Taylor CLA 2008-08-21 08:53:31 EDT
I don't think we are supposed to put product-specific information in defects.  I don't think it's even necessary though.  The stack I provided shows that the seemingly read-only method JavaProject.getPackageFragmentRoots() causes a modification to the workspace.  You could argue that all users of the above method must specify the workspace root as a scheduling rule (if being called from a Job).  However, I think that causes a proliferation of conflicting scheduling rules.  What I'm really asking for is for the above method to not modify the workspace.
Comment 11 Jerome Lanneluc CLA 2008-08-21 10:01:19 EDT
getPackageFragmentRoots() doesn't specify that it doesn't have any side effect. Also it has been like that since day 1. The side effects are needed for the build order to be correct. This cannot be changed without breaking many clients.

At best we could provide a getPackageFragmentRoots(boolean) in 3.5. The boolean parameter would control whether the side effects on the workspace are allowed. If not allowed, we would fork a job to do the side effect.
Comment 12 Grant Taylor CLA 2008-08-21 10:18:43 EDT
I understand that the API doesn't say that it doesn't change the workspace, but I think that's looking at it the wrong way.  According to your logic, we'd have to assume that every Eclipse API we call may make changes to the workspace.  This would lead to fewer (or none) opportunities for code parallelization.  Given the workspace is such a highly contended resource, I think APIs should say whether they may change the workspace or not.  I've seen this done in other places, and I think it's the right approach.

I think what you said for Eclipse 3.5 makes sense to me.  If there was a flag which ensured that the workspace is not touched, then we'd be happy.
Comment 13 Jerome Lanneluc CLA 2008-08-22 06:45:01 EDT
(In reply to comment #12)
> I understand that the API doesn't say that it doesn't change the workspace, but
> I think that's looking at it the wrong way.  According to your logic, we'd have
> to assume that every Eclipse API we call may make changes to the workspace. 
> This would lead to fewer (or none) opportunities for code parallelization. 
> Given the workspace is such a highly contended resource, I think APIs should
> say whether they may change the workspace or not.  I've seen this done in other
> places, and I think it's the right approach.
Most of the JDT/Core APIs that require a resolved classpath will have to be updated to say that they may modify the workspace. I entered bug 244937 to track this.

> I think what you said for Eclipse 3.5 makes sense to me.  If there was a flag
> which ensured that the workspace is not touched, then we'd be happy.
Since there are a lot of APIs that may modify the workspace, I think a better approach would be to add the boolean parameter to JavaCore.run(...) so that clients can say that inside the runnable workspace modifications are not allowed by JDT/Core operation.

If you agree with this approach, I will change the bug title and mark it as enhancement.
Comment 14 Grant Taylor CLA 2008-08-22 08:57:03 EDT
That sounds fine to me.  Thanks a lot.
Comment 15 Jerome Lanneluc CLA 2008-08-22 09:36:17 EDT
Marked as enhancement and changed title from "JDT is attempting to modify workspace causing hang" to "API to disallow workspace modification during JDT/Core operations"