The Source for Java Technology Collaboration

Home » java.net Forums » Java Deployment & Distribution » Java Plug-in

Thread: JApplet instantiation outside of EDT

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 20 - Last Post: Nov 6, 2008 2:52 PM by: kirillcool Threads: [ Previous | Next ]
haihovu

Posts: 10
JApplet instantiation outside of EDT
Posted: Oct 29, 2008 6:36 AM
  Click to reply to this thread Reply

Hi all, I have recently been stuck with a problem with one of my application which is an applet. The problem was encountered when I attempted to use the Substance look and feel (https://substance.dev.java.net/), whose author is very adamant about adhering to Swing's rule of creating components inside EDT (event dispatching thread) only, and will throw exceptions if this rule is violated. Below is the call trace that illustrates the problem (Java plugin 1.6.0_10-rc on Fire Fox 3, Ubuntu8.04 x86 + Win XP x86).

org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread
at org.jvnet.substance.utils.SubstanceCoreUtilities.testComponentCreationThreadingViolation(SubstanceCoreUtilities.java:2312)
at org.jvnet.substance.SubstancePanelUI.createUI(SubstancePanelUI.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
at javax.swing.UIDefaults.getUI(Unknown Source)
at javax.swing.UIManager.getUI(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 FusionLogIn.<init>(FusionLogIn.java:29) <------ My applet's constructor.
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 java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

If this is a bug in the Java plugin implementation, how would one go about getting it to the development team?

dkkopp

Posts: 11
Re: JApplet instantiation outside of EDT
Posted: Oct 29, 2008 7:26 AM   in response to: haihovu
  Click to reply to this thread Reply

Just curious, but can you post the code for your applet's constructor?

haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 29, 2008 7:38 AM   in response to: dkkopp
  Click to reply to this thread Reply

Below is an excerpt (there is not much to it, which is the way it should be), the exception was thrown in the call to super() when the applet is reloaded after the first instantiation (say when the page is reloaded or reopen in a new browser tab/window). On first instantiation no exception is thrown since the look and feel had not been set.

public FusionLogIn()
{
super();
MiLookAndFeel.setCurrentLookAndFeel("Substance Creme Coffee");
}

The custom code MiLookAndFeel.setCurrentLookAndFeel("Substance Creme Coffee"); uses the EDT to do its work.

sauvage

Posts: 65
Re: JApplet instantiation outside of EDT
Posted: Oct 29, 2008 7:51 AM   in response to: haihovu
  Click to reply to this thread Reply

You should try to set the look and feel in http://java.sun.com/j2se/1.4.2/docs/api/java/applet/Applet.html#init() instead.

haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 29, 2008 8:07 AM   in response to: sauvage
  Click to reply to this thread Reply

That makes no difference since the L&F is set using EDT (SwingUtilities.invokeAndWait) anyway. Plus the exception is thrown from inside super(), before the L&F set code is executed.

Note that this exception is thrown on second/third... instantiation of the applet after the L&F had been set in the first instantiation.

In any case the plugin should not invoke the applet's constructor from outside of the EDT.

I currently had to use a different look and feel that does not enforce this rule.

tackline

Posts: 238
Re: JApplet instantiation outside of EDT
Posted: Oct 29, 2008 3:10 PM   in response to: haihovu
  Click to reply to this thread Reply

"For legacy reasons," applets are constructed and their lifecycle methods called on an applet thread (which is not the EDT).

In fact, if init was called from the EDT, then correctly written applets would throw an Error from a call to EventQueue.invokeAndWait.

The obvious fixes would be to override JApplet.createRootPane and delay creation, or use some form of proxy look and feel which doesn't install the real PL&F until later in this case.

sauvage

Posts: 65
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 7:08 AM   in response to: tackline
  Click to reply to this thread Reply

Given this fact, I think a bug report could be submitted to substance.

kirillcool

Posts: 796
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 8:42 AM   in response to: sauvage
  Click to reply to this thread Reply

> Given this fact, I think a bug report could be submitted to substance.

As the developer of Substance, i have my reservations about calling this a "bug report". Unless Swing team comes forward and makes a very clear and official statement about the EDT rule in general, and about the applet environment in particular, i don't see this as a bug in Substance.

Thanks
Kirill

sauvage

Posts: 65
Re: JApplet instantiation outside of EDT
Posted: Nov 6, 2008 1:57 PM   in response to: kirillcool
  Click to reply to this thread Reply

Hi,

I deeply agree with you, in fact I think this is a bug in plugin implementation.
But you know, it is sun code (I won't go further), then is there an option to disable the call from EDT check in substance ?

Best regards,

Laurent.

cowwoc

Posts: 1,055
Re: JApplet instantiation outside of EDT
Posted: Nov 6, 2008 2:09 PM   in response to: sauvage
  Click to reply to this thread Reply

If you really believe it is a bug in the plugin then I would suggest you report it: http://bugs.sun.com/

sauvage

Posts: 65
Re: JApplet instantiation outside of EDT
Posted: Nov 6, 2008 2:33 PM   in response to: cowwoc
  Click to reply to this thread Reply

Well I said I won't go further but you make me lie.
My feeling is that submitting bugs to sun is often useless, so my last question to kirill was: is it possible in substance to disable the EDT call check, because it looks easier to workaround the applet lifecycle bad behaviour into substance code than into core applet plugin code.

cowwoc

Posts: 1,055
Re: JApplet instantiation outside of EDT
Posted: Nov 6, 2008 2:49 PM   in response to: sauvage
  Click to reply to this thread Reply

The plugin just underwent a major rewrite. What makes you think they won't fix yet another bug?

kirillcool

Posts: 796
Re: JApplet instantiation outside of EDT
Posted: Nov 6, 2008 2:52 PM   in response to: sauvage
  Click to reply to this thread Reply

> so my last question to kirill was: is it
> possible in substance to disable the EDT call check,
> because it looks easier to workaround the applet
> lifecycle bad behaviour into substance code than into
> core applet plugin code.

I do not have plans to provide a workaround for this scenario. The code is licensed under BSD so you're welcome to remove this check in your private build (and then continue syncing the main CVS repository for all new features and bug fixes).

Thanks
Kirill

haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 9:08 AM   in response to: tackline
  Click to reply to this thread Reply

I tried the suggestion with over-riding createRootPane(), which boils down to calling SwingUtilities invoke and wait, which stores the JRootPane in a variable which is retrieved by the calling thread. This didn't seem to work out. The first instantation was fine, but when the page was reloaded the invoke and wait invariably gets interrupted, no matter how long the wait, it's as though when the applet is reloaded, the EDT is dead-locking with the applet creation thread.

In any case I do see the points on both sides; there is the Swing rule, and then there is the legacy implementation. I hope this is resolved at some point soon 'cause I do like Substance but for applets it will have to be something else for now.

macintyrei

Posts: 8
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 9:45 AM   in response to: haihovu
  Click to reply to this thread Reply

Substance works fine in my test applet (code below). I don't do anything in the class constructor, but override the applet lifecycle methods (like init()) to do the work, and also call invokeAndWait().

import java.awt.FlowLayout;
 
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
 
 
public class TestApplet extends JApplet {
 
    public void init() {
        super.init();
        
        Runnable r = new Runnable() {
            public void run() {
                setLookAndFeel("org.jvnet.substance.skin.SubstanceCremeCoffeeLookAndFeel");
                createGUI();
            }
        };
        try {
            SwingUtilities.invokeAndWait(r);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void setLookAndFeel(String laf) {
        try {
            UIManager.setLookAndFeel(laf);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void createGUI() {
        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(new JLabel("test label"));
        getContentPane().add(new JTextField(15));
        getContentPane().add(new JCheckBox("checkbox"));
        getContentPane().add(new JRadioButton("radiobutton"));
        getContentPane().add(new JButton("button"));
    }
    
}
 


haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 10:02 AM   in response to: macintyrei
  Click to reply to this thread Reply

This only occurs in later Substance releases, e.g. 5.0, and only when the applet is reloaded, when you reload the web page, or when you open up another instance of the applet in another browser tab or window.

macintyrei

Posts: 8
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 10:08 AM   in response to: haihovu
  Click to reply to this thread Reply

I see what you mean. It works ok the first time, but subsequent reloads give the stacktrace you detailed earlier.

The only workaround I can think of would be to use java6u10 and force each applet to run in a separate jvm - although that may not be desirable for you.

<PARAM name="separate_jvm" value="true">

cowwoc

Posts: 1,055
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 9:17 AM   in response to: haihovu
  Click to reply to this thread Reply

Why can't you use SwingUtilities.invokeLater()?

haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 9:59 AM   in response to: cowwoc
  Click to reply to this thread Reply

Did both, invokeLater, invoekAndWait, put in my own wait, use sleep in stead of wait, ... no go.

cowwoc

Posts: 1,055
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 10:06 AM   in response to: haihovu
  Click to reply to this thread Reply

What stack-trace did you get when you used invokeLater()?

haihovu

Posts: 10
Re: JApplet instantiation outside of EDT
Posted: Oct 30, 2008 10:52 AM   in response to: cowwoc
  Click to reply to this thread Reply

Below is a trace (behaviour is slightly different each time but the below is the most common):

java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Thread.join(Thread.java:1143)
at java.lang.Thread.join(Thread.java:1196)
at sun.applet.AppletPanel.run(AppletPanel.java:404)
at java.lang.Thread.run(Thread.java:619)
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.awt.EventQueue.invokeAndWait(EventQueue.java:992)
at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
at FusionLogIn.createRootPane(FusionLogIn.java:70)
at javax.swing.JApplet.<init>(JApplet.java:134)
at FusionLogIn.<init>(FusionLogIn.java:62) <<<----- My constructor
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:786)
at sun.plugin.AppletViewer.createApplet(AppletViewer.java:2108)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:715)
at sun.applet.AppletPanel.run(AppletPanel.java:369)
at java.lang.Thread.run(Thread.java:619)


And here is my kludge:

/*




 XML java.net RSS