JDK-6665129 : Intermittent hangs due to shutdown of GrayBoxPainter
  • Type: Bug
  • Component: deploy
  • Sub-Component: plugin
  • Affected Version: 6u10
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-02-20
  • Updated: 2010-09-08
  • Resolved: 2008-03-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u17-crevFixed 6u10 b13Fixed
Description
Code in the GrayBoxPainter class which doesn't obey the AWT threading model is causing some applets to hang. The following (implicit, not explicit) deadlock, excerpted from the attached thread dump, is quite easily reproduced by running the SwingSet2 applet from http://java.sun.com/products/plugin/1.5.0/demos/plugin/jfc/SwingSet2/SwingSet2.html with the Java Console enabled.

In order to fix this, GrayBoxPainter.suspendPainting() and likely any other of the GrayBoxPainter's methods must be brought in line with the AWT threading model.

"Thread-24" prio=4 tid=0x03230c00 nid=0x358 waiting for monitor entry [0x0ec1f000..0x0ec1fc94]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.awt.Component.setFont(Unknown Source)
	- waiting to lock <0x22eb90c8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.setFont(Unknown Source)
	at javax.swing.JComponent.setFont(Unknown Source)
	at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
	at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
	at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
	at javax.swing.JComponent.setUI(Unknown Source)
	at javax.swing.JPanel.setUI(Unknown Source)
	at javax.swing.JPanel.updateUI(Unknown Source)
	at javax.swing.JPanel.<init>(Unknown Source)
	at javax.swing.JPanel.<init>(Unknown Source)
	at javax.swing.JPanel.<init>(Unknown Source)
	at javax.swing.JRootPane.createGlassPane(Unknown Source)
	at javax.swing.JRootPane.<init>(Unknown Source)
	at javax.swing.JApplet.createRootPane(Unknown Source)
	at javax.swing.JApplet.<init>(Unknown Source)
	at DemoModule.<init>(DemoModule.java:107)
	at ButtonDemo.<init>(ButtonDemo.java:108)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at SwingSet2.loadDemo(SwingSet2.java:822)
	at SwingSet2.loadDemos(SwingSet2.java:95)
	at SwingSet2$DemoLoadThread.run(SwingSet2.java:1410)

"thread applet-SwingSet2Applet-4" prio=4 tid=0x02a8b400 nid=0x4b8 in Object.wait() [0x0daff000..0x0daffa94]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at javax.swing.text.AbstractDocument.readLock(Unknown Source)
	- locked <0x244d6908> (a javax.swing.text.PlainDocument)
	at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(Unknown Source)
	at javax.swing.JComponent.getPreferredSize(Unknown Source)
	at javax.swing.JTextField.getPreferredSize(Unknown Source)
	at java.awt.BorderLayout.layoutContainer(Unknown Source)
	- locked <0x22eb90c8> (a java.awt.Component$AWTTreeLock)
	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.validateTree(Unknown Source)
	at java.awt.Container.validateTree(Unknown Source)
	at java.awt.Container.validateTree(Unknown Source)
	at java.awt.Container.validateTree(Unknown Source)
	at java.awt.Container.validate(Unknown Source)
	- locked <0x22eb90c8> (a java.awt.Component$AWTTreeLock)
	at sun.plugin.util.GrayBoxPainter.suspendPainting(Unknown Source)
	- locked <0x244955d8> (a sun.plugin.util.GrayBoxPainter)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

"AWT-EventQueue-5" prio=4 tid=0x032af800 nid=0x360 waiting for monitor entry [0x0e5ff000..0x0e5ffb14]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.awt.Component.invalidate(Unknown Source)
	- waiting to lock <0x22eb90c8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.invalidate(Unknown Source)
	at javax.swing.JComponent.revalidate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$RootView.preferenceChanged(Unknown Source)
	at javax.swing.text.View.preferenceChanged(Unknown Source)
	at javax.swing.text.PlainView.updateDamage(Unknown Source)
	at javax.swing.text.PlainView.insertUpdate(Unknown Source)
	at javax.swing.text.FieldView.insertUpdate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$RootView.insertUpdate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.insertUpdate(Unknown Source)
	at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source)
	at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
	at javax.swing.text.AbstractDocument.insertString(Unknown Source)
	at javax.swing.text.PlainDocument.insertString(Unknown Source)
	at javax.swing.text.AbstractDocument.replace(Unknown Source)
	at javax.swing.text.JTextComponent.setText(Unknown Source)
	at SwingSet2$5.run(SwingSet2.java:937)
	at java.awt.event.InvocationEvent.dispatch(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)

"AWT-EventQueue-1" prio=6 tid=0x0312a800 nid=0x2c8 waiting for monitor entry [0x035cf000..0x035cfb94]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.awt.Component.invalidate(Unknown Source)
	- waiting to lock <0x22eb90c8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.invalidate(Unknown Source)
	at javax.swing.JComponent.revalidate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$RootView.preferenceChanged(Unknown Source)
	at javax.swing.text.View.preferenceChanged(Unknown Source)
	at javax.swing.text.PlainView.updateDamage(Unknown Source)
	at javax.swing.text.PlainView.insertUpdate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$RootView.insertUpdate(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.insertUpdate(Unknown Source)
	at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source)
	at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
	at javax.swing.text.AbstractDocument.insertString(Unknown Source)
	at javax.swing.text.PlainDocument.insertString(Unknown Source)
	at javax.swing.JTextArea.append(Unknown Source)
	at com.sun.deploy.util.ConsoleWindow$25.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)

Comments
SUGGESTED FIX http://sa.sfbay.sun.com/projects/deployment_data/6u10/6665129.0 testcase: http://j2se.east.sun.com/deployment/www/tests/1.6.0_10/6665129/
20-02-2008

EVALUATION Worked around deadlocks caused by thread-unsafety of GrayBoxPainter by performing operations requiring AWT tree lock and potentially causing unbounded amounts of user code to run to be done on the Event Dispatch Thread. Note that another variant of this fix was attempted which moved more work on to the Event Dispatch Thread synchronously (using EventQueue.invokeAndWait()), but this caused significant breakage. Therefore this smaller and more targeted fix was chosen.
20-02-2008