Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 318716 - Deadlock because ClasspathContainerVirtualComponent initialized Java too aggressively.
Summary: Deadlock because ClasspathContainerVirtualComponent initialized Java too aggr...
Status: RESOLVED FIXED
Alias: None
Product: WTP Java EE Tools
Classification: WebTools
Component: jst.j2ee (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows Server 2003
: P3 normal (vote)
Target Milestone: 3.2.1   Edit
Assignee: Jason Sholl CLA
QA Contact: Chuck Bridgham CLA
URL:
Whiteboard: PMC_approved
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-02 09:19 EDT by Jason Sholl CLA
Modified: 2010-07-08 15:34 EDT (History)
1 user (show)

See Also:
david_williams: pmc_approved+
jsholl: pmc_approved? (raghunathan.srinivasan)
jsholl: pmc_approved? (naci.dai)
jsholl: pmc_approved? (deboer)
jsholl: pmc_approved? (neil.hauge)
jsholl: pmc_approved? (kaloyan)
cbridgha: review+


Attachments
patch for 3.2.1 (3.24 KB, patch)
2010-07-02 09:22 EDT, Jason Sholl CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Sholl CLA 2010-07-02 09:19:55 EDT
This can be reproduced using the attached zip of projects and utility jar.  The you will also need to setup a Java user library called "MyOther" and point to the utility jar on disk.

The below pile of stack traces is the full deadlock.  The problem is that JDT is still being triggered via the DependencyGraph update.  The solution is simple and safe because in this particular case the ClasspathContainerVirtualComponent can lazily initialize its JDT portion which is not needed by the DependencyGraph.

Here is the section in question:

WorkManager.checkIn(ISchedulingRule, IProgressMonitor) line: 118 
Workspace.prepareOperation(ISchedulingRule, IProgressMonitor) line: 1914 
Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) line: 1970 
JavaModelManager.initializeAllContainers(IJavaProject, IPath) line: 2653 
JavaModelManager.getClasspathContainer(IPath, IJavaProject) line: 1845 
JavaCore.getClasspathContainer(IPath, IJavaProject) line: 2705           <<<<<<<<<<<<<<<<<<<<<<<<< Need to stop this portion
ClasspathContainerVirtualComponent.<init>(IProject, IVirtualComponent, String) line: 47 
ClasspathContainerReferenceResolver.resolve(IVirtualComponent, ReferencedComponent) line: 43 
StructureEdit.createVirtualReference(IVirtualComponent, ReferencedComponent) line: 289 
EARVirtualComponent(VirtualComponent).getRawReferences() line: 400 
DependencyGraphImpl$GraphUpdateJob$1.run() line: 391 
SafeRunner.run(ISafeRunnable) line: 42 
DependencyGraphImpl$GraphUpdateJob.run(IProgressMonitor) line: 359 


Full stack traces:

org.eclipse.equinox.launcher.Main at localhost:4255 (Suspended) 
Thread [main] (Suspended) 
OS.WaitMessage() line: not available [native method] 
Display.sleep() line: 4553 
IDEWorkbenchAdvisor(WorkbenchAdvisor).eventLoopIdle(Display) line: 364 
IDEWorkbenchAdvisor.eventLoopIdle(Display) line: 887 
Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2630 
Workbench.runUI() line: 2593 
Workbench.access$4(Workbench) line: 2427 
Workbench$7.run() line: 670 
Realm.runWithDefault(Realm, Runnable) line: 332 
Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 663 
PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149 
IDEApplication.start(IApplicationContext) line: 115 
EclipseAppHandle.run(Object) line: 196 
EclipseAppLauncher.runApplication(Object) line: 110 
EclipseAppLauncher.start(Object) line: 79 
EclipseStarter.run(Object) line: 369 
EclipseStarter.run(String[], Runnable) line: 179 
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] 
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 48 
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 37 
Method.invoke(Object, Object...) line: 600 
Main.invokeFramework(String[], URL[]) line: 619 
Main.basicRun(String[]) line: 574 
Main.run(String[]) line: 1407 
Main.main(String[]) line: 1383 
Daemon System Thread [JIT Compilation Thread] (Suspended) 
Daemon Thread [Signal Dispatcher] (Suspended) 
Daemon System Thread [Gc Slave Thread] (Suspended) 
Daemon Thread [Attach handler] (Suspended) 
Daemon Thread [file lock watchdog] (Suspended) 
Daemon Thread [State Data Manager] (Suspended) 
Daemon Thread [Start Level Event Dispatcher] (Suspended) 
Daemon System Thread [Finalizer thread] (Suspended) 
Daemon Thread [Framework Event Dispatcher] (Suspended) 
Daemon Thread [[Timer] - Main Queue Handler] (Suspended) 
Daemon Thread [Bundle File Closer] (Suspended) 
Daemon Thread [[ThreadPool Manager] - Idle Thread] (Suspended) 
Thread [Worker-JM] (Suspended) 
waiting for: ArrayList<E> (id=1110) 
Object.wait(long, int) line: not available [native method] 
ArrayList<E>(Object).wait(long) line: 196 
InternalWorker.run() line: 58 
Daemon Thread [Java indexing] (Suspended) 
Daemon Thread [JavaScript indexing] (Suspended) 
Thread [Worker-1] (Suspended) 
Thread.sleep(long, int) line: not available [native method] 
Thread.sleep(long) line: 851 
DependencyGraphImpl.waitForAllUpdates(IProgressMonitor) line: 581 
DependencyGraphImpl.getReferencingComponents(IProject) line: 87 
J2EEModuleVirtualComponent(VirtualComponent).getReferencingComponents() line: 573 
EarUtilities.getReferencingEARProjects(IProject) line: 211 
J2EEModuleVirtualComponent.calculateManifestReferences(IVirtualComponent, boolean) line: 320 
J2EEModuleVirtualComponent.cacheManifestReferences() line: 310 
J2EEModuleVirtualComponent.getReferences(boolean, boolean) line: 153 
J2EEComponentClasspathContainer.update() line: 192 
J2EEComponentClasspathContainer.install(IPath, IJavaProject) line: 367 
J2EEComponentClasspathInitializer.initialize(IPath, IJavaProject) line: 48 
JavaModelManager.initializeContainer(IJavaProject, IPath) line: 2707 
JavaModelManager$11.run(IProgressMonitor) line: 2613 
JavaModelManager.initializeAllContainers(IJavaProject, IPath) line: 2651 
JavaModelManager.getClasspathContainer(IPath, IJavaProject) line: 1845 
JavaCore.getClasspathContainer(IPath, IJavaProject) line: 2705 
JavaProject.resolveClasspath(IClasspathEntry[], IClasspathEntry[], boolean, boolean) line: 2645 
JavaProject.resolveClasspath(JavaModelManager$PerProjectInfo, boolean, boolean) line: 2783 
ClasspathChange.generateDelta(JavaElementDelta, boolean) line: 218 
DeltaProcessor.resourceChanged(IResourceChangeEvent) line: 1916 
DeltaProcessingState.resourceChanged(IResourceChangeEvent) line: 470 
NotificationManager$2.run() line: 291 
SafeRunner.run(ISafeRunnable) line: 42 
NotificationManager.notify(ResourceChangeListenerList$ListenerEntry[], IResourceChangeEvent, boolean) line: 285 
NotificationManager.broadcastChanges(ElementTree, ResourceChangeEvent, boolean) line: 149 
Workspace.broadcastPostChange() line: 327 
Workspace.endOperation(ISchedulingRule, boolean, IProgressMonitor) line: 1181 
Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) line: 1984 
NotificationManager$NotifyJob.run(IProgressMonitor) line: 40 
Worker.run() line: 54 
Thread [Worker-3] (Suspended) 
waiting for: Object (id=1999) 
Object.wait(long, int) line: not available [native method] 
Object.wait(long) line: 196 
ThreadJob.waitForRun(ThreadJob, IProgressMonitor, InternalJob, Thread) line: 269 
ThreadJob.joinRun(ThreadJob, IProgressMonitor) line: 199 
ImplicitJobs.begin(ISchedulingRule, IProgressMonitor, boolean) line: 92 
JobManager.beginRule(ISchedulingRule, IProgressMonitor) line: 285 
StringPoolJob.run(IProgressMonitor) line: 99 
Worker.run() line: 54 
Thread [Worker-4] (Suspended) 
waiting for: Semaphore (id=1687) 
Object.wait(long, int) line: not available [native method] 
Semaphore(Object).wait(long) line: 196 
Semaphore.acquire(long) line: 39 
OrderedLock.doAcquire(Semaphore, long) line: 176 
OrderedLock.acquire(long) line: 110 
DependencyGraphImpl.waitForAllUpdates(IProgressMonitor) line: 588 
DependencyGraphImpl.getReferencingComponents(IProject) line: 87 
J2EEModuleVirtualComponent(VirtualComponent).getReferencingComponents() line: 573 
EarUtilities.getReferencingEARProjects(IProject) line: 211 
J2EEModuleVirtualComponent.calculateManifestReferences(IVirtualComponent, boolean) line: 320 
J2EEModuleVirtualComponent.cacheManifestReferences() line: 310 
J2EEModuleVirtualComponent.getReferences(boolean, boolean) line: 153 
J2EEComponentClasspathContainer.update() line: 192 
J2EEComponentClasspathContainer.install(IPath, IJavaProject) line: 367 
J2EEComponentClasspathInitializer.initialize(IPath, IJavaProject) line: 48 
JavaModelManager.initializeContainer(IJavaProject, IPath) line: 2707 
JavaModelManager$11.run(IProgressMonitor) line: 2613 
Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) line: 1975 
JavaModelManager.initializeAllContainers(IJavaProject, IPath) line: 2653 
JavaModelManager.getClasspathContainer(IPath, IJavaProject) line: 1845 
JavaCore.initializeAfterLoad(IProgressMonitor) line: 3463 
InitializeAfterLoadJob$RealJob.run(IProgressMonitor) line: 35 
Worker.run() line: 54 
Thread [Worker-2] (Suspended) 
waiting for: Semaphore (id=1302) 
Object.wait(long, int) line: not available [native method] 
Semaphore(Object).wait(long) line: 196 
Semaphore.acquire(long) line: 39 
OrderedLock.doAcquire(Semaphore, long) line: 176 
OrderedLock.acquire(long) line: 110 
OrderedLock.acquire() line: 84 
WorkManager.checkIn(ISchedulingRule, IProgressMonitor) line: 118 
Workspace.prepareOperation(ISchedulingRule, IProgressMonitor) line: 1914 
Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) line: 1970 
JavaModelManager.initializeAllContainers(IJavaProject, IPath) line: 2653 
JavaModelManager.getClasspathContainer(IPath, IJavaProject) line: 1845 
JavaCore.getClasspathContainer(IPath, IJavaProject) line: 2705 
ClasspathContainerVirtualComponent.<init>(IProject, IVirtualComponent, String) line: 47 
ClasspathContainerReferenceResolver.resolve(IVirtualComponent, ReferencedComponent) line: 43 
StructureEdit.createVirtualReference(IVirtualComponent, ReferencedComponent) line: 289 
EARVirtualComponent(VirtualComponent).getRawReferences() line: 400 
DependencyGraphImpl$GraphUpdateJob$1.run() line: 391 
SafeRunner.run(ISafeRunnable) line: 42 
DependencyGraphImpl$GraphUpdateJob.run(IProgressMonitor) line: 359 
Worker.run() line: 54 
Thread [Worker-5] (Suspended) 
waiting for: Semaphore (id=1371) 
Object.wait(long, int) line: not available [native method] 
Semaphore(Object).wait(long) line: 196 
Semaphore.acquire(long) line: 39 
OrderedLock.doAcquire(Semaphore, long) line: 176 
OrderedLock.acquire(long) line: 110 
OrderedLock.acquire() line: 84 
WorkManager.checkIn(ISchedulingRule, IProgressMonitor) line: 118 
Workspace.prepareOperation(ISchedulingRule, IProgressMonitor) line: 1914 
Workspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) line: 1970 
JavaModelManager.initializeAllContainers(IJavaProject, IPath) line: 2653 
JavaModelManager.getClasspathContainer(IPath, IJavaProject) line: 1845 
JavaCore.getClasspathContainer(IPath, IJavaProject) line: 2705 
JavaProject.resolveClasspath(IClasspathEntry[], IClasspathEntry[], boolean, boolean) line: 2645 
JavaProject.resolveClasspath(JavaModelManager$PerProjectInfo, boolean, boolean) line: 2783 
JavaProject.getResolvedClasspath() line: 1915 
JavaProject.isOnClasspath(IResource) line: 2193 
BuildpathIndicatorLabelDecorator.getOverlay(Object) line: 47 
BuildpathIndicatorLabelDecorator.decorate(Object, IDecoration) line: 34 
LightweightDecoratorDefinition.decorate(Object, IDecoration) line: 269 
LightweightDecoratorManager$LightweightRunnable.run() line: 81 
SafeRunner.run(ISafeRunnable) line: 42 
LightweightDecoratorManager.decorate(Object, DecorationBuilder, LightweightDecoratorDefinition) line: 365 
LightweightDecoratorManager.getDecorations(Object, DecorationBuilder) line: 347 
DecorationScheduler$1.ensureResultCached(Object, boolean, IDecorationContext) line: 371 
DecorationScheduler$1.run(IProgressMonitor) line: 331 
Worker.run() line: 54 
Thread [Worker-6] (Suspended) 
waiting for: Semaphore (id=1825) 
Object.wait(long, int) line: not available [native method] 
Semaphore(Obje
Comment 1 Jason Sholl CLA 2010-07-02 09:22:17 EDT
Created attachment 173303 [details]
patch for 3.2.1

Moves the JDT initialization portion to a lazily called init method.  Simple synchronization ensures the two initialized variables are only set once.  (Turns out this method calls back into itself).
Comment 2 Chuck Bridgham CLA 2010-07-02 10:34:37 EDT
approved
Comment 3 Jason Sholl CLA 2010-07-02 15:20:29 EDT
    * Explain why you believe this is a stop-ship defect. Or, if it is a "hotbug" (requested by an adopter) please document it as such. 

Deadlock; and an easily reproducible one too.

    * Is there a work-around? If so, why do you believe the work-around is insufficient? 

No

    * How has the fix been tested? Is there a test case attached to the bugzilla record? Has a JUnit Test been added? 

UI & JUnits

    * Give a brief technical overview. Who has reviewed this fix? 

Moves the JDT initialization portion to a lazily called init method.  Simple
synchronization ensures the two initialized variables are only set once. 
(Turns out this method calls back into itself).  Reviewed by Chuck and Jason

    * What is the risk associated with this fix? 
None
Comment 4 David Williams CLA 2010-07-05 00:31:37 EDT
I guess by now, everyone knows my view of fixing deadlock problems ... fixing one, if if correct fix, may cause other threading issues to pop up ... so, hope scenarios that use this code can be tested extensively.
Comment 5 Jason Sholl CLA 2010-07-07 11:35:52 EDT
Code checked into head for WTP 3.2.1