Bug 507874 - OpenJDK JNLP launcher violates Swing threading rules
OpenJDK JNLP launcher violates Swing threading rules
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: java-1.6.0-openjdk (Show other bugs)
rawhide
All Linux
low Severity medium
: ---
: ---
Assigned To: Lillian Angel
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2009-06-24 11:38 EDT by Kirill Grouchnikov
Modified: 2009-07-07 10:28 EDT (History)
6 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2009-07-07 10:28:11 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Kirill Grouchnikov 2009-06-24 11:38:23 EDT
WebStart launcher violates Swing threading rules by creating the main frame off the Event Dispatch Thread.

The relevant part of the stack trace:

at test.substance.ribbon.NewCheckRibbon.main(NewCheckRibbon.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at net.sourceforge.jnlp.Launcher.launchApplication(Launcher.java:364)
at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:600)

where test.substance.ribbon.NewCheckRibbon is the main application class. Swing threading rules state that any operation related to UI *must* run on the Event Dispatch Thread.

To reproduce, click https://substance-flamingo.dev.java.net/webstart/testRibbon.jnlp which runs under Substance look-and-feel. Substance traces the EDT violations and will throw an exception under OpenJDK - but not under Sun's JNLP launcher.
Comment 1 Omair Majid 2009-06-25 14:46:44 EDT
Hi Kirill,

Thanks for reporting this bug. I really appreciate you taking the time to test flamingo and substance with IcedTea6. I can reproduce the stack traces but I am not sure if this is a bug in IcedTea6's WebStart (Netx), Swing, or in the test program. Any help in pinpointing the problem is appreciated.

Netx doesn't know anything about the application; it simply calls the application's main method and trusts it to do the right thing. It doesn't run the application in the EDT because it has no clue what the application does - perhaps the application is a computation intensive program which wont be able to update the ui because the main thread is the EDT. So Netx runs the main() method in a normal thread. As far as I can tell (by writing a program that dumps out the stack), Sun's Web Start implementation does the same thing.

Also, Netx does not create these swing components, the test.substance.ribbon.NewCheckRibbon class does. Looking at the stack trace, I see this bit:
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
at test.substance.ribbon.NewCheckRibbon.main(NewCheckRibbon.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at net.sourceforge.jnlp.Launcher.launchApplication(Launcher.java:387)
at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:623)

Seems like setSkin calls a UI method on the normal thread and not through the EDT. Now I am not sure if this is a bug in setSkin() or if Sun's JRE automatically calls updateComponentTreeUI0 (or perhaps some other method?) on the EDT. Could you post a stack trace showing what happens when setSkin() is called using Sun's JRE?

Thanks.
Comment 2 Kirill Grouchnikov 2009-06-25 16:14:36 EDT
Hi Omair

Looking at the code of that class, the primary application window is created on the EDT (wrapped with SwingUtilities.invokeLater), but the look-and-feel is set outside it. In SubstanceLookAndFeel.setSkin i iterate over all open windows (with Window.getWindows) and update them with SwingUtilities.updateComponentTree. 

So it looks like there is another window already existing in this VM prior to the main() method being launched by the net.sourceforge.jnlp.Launcher class. Perhaps it's the WebStart console window?

Looks like i need to move the call to SubstanceLookAndFeel.setSkin to also be called on the EDT and not rely that there are no open windows prior to the main() method being called.

Let me change the code and ask the original bug submitter to verify this in his environment.

Thanks
Kirill
Comment 3 Omair Majid 2009-06-25 16:37:01 EDT
(In reply to comment #2)
> So it looks like there is another window already existing in this VM prior to
> the main() method being launched by the net.sourceforge.jnlp.Launcher class.
> Perhaps it's the WebStart console window?
Ah, yes. Netx is likely to create several windows before calling main(), including splash screens, download indicators and warning dialogs about any certificate issues.  

> Let me change the code and ask the original bug submitter to verify this in his
> environment.
Thanks for the fix.

Cheers,
Omair
Comment 4 Kirill Grouchnikov 2009-06-26 14:44:27 EDT
Omair,

The EDT-related exceptions are gone after i moved the call to SubstanceLookAndFeel.setSkin into SwingUtilities.invokeLater. However, the test application still fails under OpenJDK, with the following exceptions:

UIDefaults.getUI() failed: no ComponentUI class for:
javax.swing.JRootPane[,9,41,596x60,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=]
java.lang.Error
	at javax.swing.UIDefaults.getUIError(UIDefaults.java:728)
	at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:134)
	at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
	at javax.swing.UIManager.getUI(UIManager.java:1015)
	at javax.swing.JRootPane.updateUI(JRootPane.java:482)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1231)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
	at test.substance.ribbon.NewCheckRibbon$3.run(NewCheckRibbon.java:167)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
UIDefaults.getUI() failed: no ComponentUI class for:
javax.swing.JPanel[null.glassPane,0,0,596x60,hidden,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.lang.Error
	at javax.swing.UIDefaults.getUIError(UIDefaults.java:728)
	at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:134)
	at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
	at javax.swing.UIManager.getUI(UIManager.java:1015)
	at javax.swing.JPanel.updateUI(JPanel.java:126)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1231)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
	at test.substance.ribbon.NewCheckRibbon$3.run(NewCheckRibbon.java:167)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
UIDefaults.getUI() failed: no ComponentUI class for:
javax.swing.JPanel[null.contentPane,0,0,596x60,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
java.lang.Error
	at javax.swing.UIDefaults.getUIError(UIDefaults.java:728)
	at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:134)
	at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
	at javax.swing.UIManager.getUI(UIManager.java:1015)
	at javax.swing.JPanel.updateUI(JPanel.java:126)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1231)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
	at test.substance.ribbon.NewCheckRibbon$3.run(NewCheckRibbon.java:167)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
UIDefaults.getUI() failed: no ComponentUI class for:
net.sourceforge.jnlp.cache.DefaultDownloadIndicator$DownloadPanel[,0,0,596x60,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
java.lang.Error
	at javax.swing.UIDefaults.getUIError(UIDefaults.java:728)
	at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:134)
	at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
	at javax.swing.UIManager.getUI(UIManager.java:1015)
	at javax.swing.JPanel.updateUI(JPanel.java:126)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1231)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
	at test.substance.ribbon.NewCheckRibbon$3.run(NewCheckRibbon.java:167)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
UIDefaults.getUI() failed: no ComponentUI class for:
javax.swing.JLabel[,0,0,596x18,alignmentX=0.0,alignmentY=0.0,border=,flags=8388608,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=Downloading
Ribbon demo - Substance look and feel: 100%
Complete.,verticalAlignment=CENTER,verticalTextPosition=CENTER]
java.lang.Error
	at javax.swing.UIDefaults.getUIError(UIDefaults.java:728)
	at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:134)
	at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
	at javax.swing.UIManager.getUI(UIManager.java:1015)
	at javax.swing.JLabel.updateUI(JLabel.java:273)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1231)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1246)
	at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1222)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:1968)
	at org.jvnet.substance.SubstanceLookAndFeel.setSkin(SubstanceLookAndFeel.java:2044)
	at test.substance.ribbon.NewCheckRibbon$3.run(NewCheckRibbon.java:167)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

I'm not sure if this is a problem with Substance or OpenJDK (this demo runs without errors on Sun JDK), and it doesn't look like it has anything to do with EDT. So this bug can be marked as CLOSED, and perhaps a new issue can be created to track the new problem (with the UIManager.getUI).

Thanks
Kirill
Comment 5 Kirill Grouchnikov 2009-07-02 00:19:09 EDT
Wasn't this bug marked as CLOSED? I can confirm that this specific problem was in my code, and not in the WebStart launcher. It was a wrong assumption based on the Sun JDK WebStart behavior.

Thanks
Kirill
Comment 6 Kirill Grouchnikov 2009-07-02 00:20:09 EDT
I've created https://bugzilla.redhat.com/show_bug.cgi?id=509301 to track the new stack traces.

Thanks
Kirill

Note You need to log in before you can comment on or make changes to this bug.