Community
Participate
Working Groups
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
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).
approved
* 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
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.
Code checked into head for WTP 3.2.1