Forum Discussion

Boss_Media_Supp's avatar
Boss_Media_Supp
New Contributor
12 years ago

Deadlock due to UI updates from user threads

Snippet from thread dump of SoapUI Pro 4.5.2:


Found one Java-level deadlock:
=============================
"LogList Updater for script log":
waiting to lock monitor 0x000000000fe86928 (object 0x0000000780000fd8, a java.awt.Component$AWTTreeLock),
which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
waiting to lock monitor 0x000000001c795c58 (object 0x0000000781c00598, a java.lang.StringBuilder),
which is held by "LogList Updater for script log"

Java stack information for the threads listed above:
===================================================
"LogList Updater for script log":
at java.awt.Window.getOpacity(Unknown Source)
- waiting to lock <0x0000000780000fd8> (a java.awt.Component$AWTTreeLock)
at sun.awt.SunToolkit.isContainingTopLevelTranslucent(Unknown Source)
at sun.awt.windows.WComponentPeer.isAccelCapable(Unknown Source)
at sun.java2d.d3d.D3DSurfaceData$D3DWindowSurfaceData.restoreSurface(Unknown Source)
at sun.java2d.d3d.D3DScreenUpdateManager.validate(Unknown Source)
at sun.java2d.d3d.D3DScreenUpdateManager.createGraphics(Unknown Source)
at sun.awt.windows.WComponentPeer.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JFrame.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at java.awt.Component.getGraphics(Unknown Source)
at javax.swing.JComponent.getGraphics(Unknown Source)
at javax.swing.JComponent.safelyGetGraphics(Unknown Source)
- locked <0x0000000781c00598> (a java.lang.StringBuilder)
at javax.swing.JComponent.safelyGetGraphics(Unknown Source)
at javax.swing.JViewport.setViewPosition(Unknown Source)
at javax.swing.JViewport.scrollRectToVisible(Unknown Source)
at javax.swing.JComponent.scrollRectToVisible(Unknown Source)
at javax.swing.JList.ensureIndexIsVisible(Unknown Source)
at com.eviware.soapui.impl.wsdl.panels.testcase.JTestRunLog.addText(JTestRunLog.java:293)
- locked <0x0000000787c9d090> (a com.eviware.soapui.impl.wsdl.panels.testcase.JTestCaseTestRunLog)
at com.eviware.soapui.impl.wsdl.panels.testcase.WsdlTestCaseDesktopPanel$InternalTestRunListener.beforeRun(WsdlTestCaseDesktopPanel.java:448)
at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.notifyBeforeRun(AbstractTestCaseRunner.java:321)
at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.internalRun(AbstractTestCaseRunner.java:118)
at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.internalRun(AbstractTestCaseRunner.java:43)
at com.eviware.soapui.impl.wsdl.support.AbstractTestRunner.run(AbstractTestRunner.java:135)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
"AWT-EventQueue-0":
at javax.swing.JComponent.safelyGetGraphics(Unknown Source)
- waiting to lock <0x0000000781c00598> (a java.lang.StringBuilder)
at javax.swing.JComponent.safelyGetGraphics(Unknown Source)
at javax.swing.JViewport.setViewPosition(Unknown Source)
at javax.swing.ViewportLayout.layoutContainer(Unknown Source)
at java.awt.Container.layout(Unknown Source)
at java.awt.Container.doLayout(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validate(Unknown Source)
- locked <0x0000000780000fd8> (a java.awt.Component$AWTTreeLock)
at javax.swing.RepaintManager$2.run(Unknown Source)
at javax.swing.RepaintManager$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Found 1 deadlock.


It looks very much like com.eviware.soapui.impl.wsdl.panels.testcase.WsdlTestCaseDesktopPanel$InternalTestRunListener.beforeRun is updating the UI from the user thread instead of doing it via the AWT-EventQueue thread. The result in this case is a dead-lock and SoapUI freezes.

See http://docs.oracle.com/javase/6/docs/ap ... mmary.html for instance (section about Swing's Threading Policy) regarding multi-threaded UI updates.
Full thread dump attached for reference (as a side note I wonder if it is really a good idea to have that many "log updater threads").

3 Replies

  • Hi,

    We will take a further look into what you reported, but can you give some details in how this deadlock happened? Such as what you were doing in SoapUI, or type of testcase you were running to cause this to happen.



    Regards,
    Marcus
    SmartBear Support
  • Well, I'm not quite sure what I was doing inside SoapUI when the deadlock occurred. I didn't actively use it at all really, but i might have left a test case loop running (by the "Loop TestCase continuously" feature) when I last used SoapUI (a few hours before the deadlock occurred).
    Either way, I think it is fairly obvious from the thread dump where the bug is (you are violating the general rule "All Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread." mentioned in the javadocs I linked to).
    I certainly agree that this may be hard to reproduce and test, but the fix is relatively easy - just use SwingUtilities.invokeLater() or something equivalent to call JTestRunLog.addText() from WsdlTestCaseDesktopPanel$InternalTestRunListener.beforeRun()

    EDIT: Found a stackoverflow entry that you might find interesting: http://stackoverflow.com/questions/3014 ... at-runtime
  • Hi,

    I have opened defect SOAP-1137 for this issue.
    Thanks for your feedback.



    Regards,
    Marcus
    SmartBear Support