jdic
  1. jdic
  2. JDIC-488

Cant dispose JFrame if browser is a component

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Trivial Trivial
    • Resolution: Unresolved
    • Affects Version/s: 0.9
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      Operating System: Windows XP
      Platform: PC

    • Issuezilla Id:
      488

      Description

      Hi folks,

      If the WebBrowser component is added to a JFrame the JFrame can no longer be
      disposed. Below is test code you can run to repeat the bug.

      import org.jdesktop.jdic.browser.WebBrowser;

      import javax.swing.*;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;

      public class Test
      {
      public static void main( String[] args )
      {
      final JFrame jf = new JFrame("Testing");
      jf.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );

      //comment out the following line
      final WebBrowser webBrowser = new WebBrowser(false);

      jf.addWindowListener(new WindowAdapter()
      {
      public void windowClosing( WindowEvent e)

      { //comment out the following line webBrowser.dispose(); jf.removeAll(); jf.dispose(); System.out.println("\n\nprogram should finish...but doesn't!!!"); }

      });

      //comment out the following line
      jf.getContentPane().add( webBrowser );

      jf.setBounds( 0,0,400,400);
      jf.setVisible( true );
      }

      }

      If you run the above example then close the JFrame window, the JVM never exits,
      however if you run the same example with the WebBrowser lines commented out,
      the JVM exits correctly. Below is stack dump of all the running threads when
      the JVM hangs.

      Full thread dump Java HotSpot(TM) Client VM (1.5.0_03-b07 mixed mode, sharing):

      "Thread-3" prio=5 tid=0x02cdcc60 nid=0xa64 runnable [0x0332f000..0x0332fc68]
      at java.io.FileInputStream.readBytes(Native Method)
      at java.io.FileInputStream.read(FileInputStream.java:194)
      at java.io.BufferedInputStream.read1(BufferedInputStream.java:254)
      at java.io.BufferedInputStream.read(BufferedInputStream.java:313)

      • locked <0x22aa68e0> (a java.io.BufferedInputStream)
        at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)
        at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)
      • locked <0x22ab8c98> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:167)
        at java.io.BufferedReader.fill(BufferedReader.java:136)
        at java.io.BufferedReader.readLine(BufferedReader.java:299)
      • locked <0x22ab8c98> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:362)
        at
        org.jdesktop.jdic.browser.internal.NativeEventThread$StreamGobbler.run(Unknown
        Source)

      "Thread-2" prio=5 tid=0x02cdcab0 nid=0xc48 runnable [0x032ef000..0x032efce8]
      at java.io.FileInputStream.readBytes(Native Method)
      at java.io.FileInputStream.read(FileInputStream.java:194)
      at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)
      at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)
      at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)

      • locked <0x22aaeac8> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:167)
        at java.io.BufferedReader.fill(BufferedReader.java:136)
        at java.io.BufferedReader.readLine(BufferedReader.java:299)
      • locked <0x22aaeac8> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:362)
        at
        org.jdesktop.jdic.browser.internal.NativeEventThread$StreamGobbler.run(Unknown
        Source)

      "DestroyJavaVM" prio=5 tid=0x000371a8 nid=0xac waiting on condition
      [0x00000000..0x0007fae8]

      "EventThread" prio=5 tid=0x02cc8dc8 nid=0x598 waiting on condition
      [0x0323f000..0x0323f9e8]
      at java.lang.Thread.sleep(Native Method)
      at org.jdesktop.jdic.browser.internal.NativeEventThread.run(Unknown
      Source)

      "AWT-Windows" daemon prio=7 tid=0x02cbfcd8 nid=0xe90 runnable
      [0x0316f000..0x0316fa68]
      at sun.awt.windows.WToolkit.eventLoop(Native Method)
      at sun.awt.windows.WToolkit.run(WToolkit.java:269)
      at java.lang.Thread.run(Thread.java:595)

      "Java2D Disposer" daemon prio=10 tid=0x02cbe620 nid=0xb4c in Object.wait()
      [0x030ef000..0x030efb68]
      at java.lang.Object.wait(Native Method)

      • waiting on <0x22b004c8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
      • locked <0x22b004c8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at sun.java2d.Disposer.run(Disposer.java:107)
        at java.lang.Thread.run(Thread.java:595)

      "Monitor Ctrl-Break" daemon prio=5 tid=0x00aca8f0 nid=0xf80 runnable
      [0x02fcf000..0x02fcfbe8]
      at com.intellij.rt.execution.application.AppMain.triggerControlBreak
      (Native Method)
      at com.intellij.rt.execution.application.AppMain.access$000
      (AppMain.java:16)
      at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:62)
      at java.lang.Thread.run(Thread.java:595)

      "Low Memory Detector" daemon prio=5 tid=0x00a6d4d0 nid=0xa74 runnable
      [0x00000000..0x00000000]

      "CompilerThread0" daemon prio=10 tid=0x00a6c140 nid=0xf0c waiting on condition
      [0x00000000..0x02c0f6cc]

      "Signal Dispatcher" daemon prio=10 tid=0x00a6b450 nid=0x9d8 waiting on
      condition [0x00000000..0x00000000]

      "Finalizer" daemon prio=9 tid=0x00a688b8 nid=0x3e8 in Object.wait()
      [0x02b8f000..0x02b8fa68]
      at java.lang.Object.wait(Native Method)

      • waiting on <0x22f834a0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
      • locked <0x22f834a0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

      "Reference Handler" daemon prio=10 tid=0x00a39e98 nid=0xf60 in Object.wait()
      [0x02b4f000..0x02b4fae8]
      at java.lang.Object.wait(Native Method)

      • waiting on <0x22f830c8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:474)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
      • locked <0x22f830c8> (a java.lang.ref.Reference$Lock)

      "VM Thread" prio=10 tid=0x00a67bb8 nid=0xb58 runnable

      "VM Periodic Task Thread" prio=10 tid=0x00a8ff28 nid=0xbb8 waiting on condition

      Seems like you've forgotten to wake up the sleeping jdic thread.

      You might be wondering why I just dont call System.exit() or
      JFrame.EXIT_ON_CLOSE. However this is a simple test class. My real code runs
      from a system tray applet, which comunicates with a remote server. From time
      to time the server tells the tray applet to open a web browser I need to be
      able to call dispose as system.exit would end my tray applet.

      Any ideas what's going wrong and is it fixable?

      Kind Regards
      Chris.

        Activity

        Hide
        cknight19 added a comment -

        The Browser is unusable whilst this issue remains unsolved.

        Show
        cknight19 added a comment - The Browser is unusable whilst this issue remains unsolved.
        Hide
        cknight19 added a comment -

        Good to see the developers knocking through these bugs so quickely!!!

        Anyway, I managed to solve the problem myself. And for anyone else that wants
        the solution you will need to get the JDIC source and modify the following
        lines :-

        In org.jdesktop.jdic.browser.WebBrowser.java, in the removeNotify method change
        line 169 "WebBrowser.super.removeNotify();" to look like this :-
        try

        { eventThread.interrupt(); WebBrowser.this.getPeer().destroyBuffers(); WebBrowser.this.getPeer().dispose(); WebBrowser.super.removeNotify(); }

        catch(Exception e) {}

        In org.jdesktop.jdic.browser.NativeEventThread.java, change the main event
        loop's ( line 112 ) try/catch block to look like this :-
        try

        { Thread.sleep(1); }

        catch (Exception e) {
        try

        {nativeBrowser.getInputStream().close();}

        catch(Exception e1){}
        try

        {nativeBrowser.getErrorStream().close();}

        catch(Exception e1){}
        try

        {nativeBrowser.getOutputStream().close();}

        catch(Exception e1){}
        processEvents();
        try

        {messenger.portListening();}

        catch(Exception ex){}
        processIncomingMessage(messenger.getMessage());
        nativeBrowser.destroy();
        return;
        }

        Now any JFrame that includes a WebBrowser object will dispose correctly.

        Show
        cknight19 added a comment - Good to see the developers knocking through these bugs so quickely!!! Anyway, I managed to solve the problem myself. And for anyone else that wants the solution you will need to get the JDIC source and modify the following lines :- In org.jdesktop.jdic.browser.WebBrowser.java, in the removeNotify method change line 169 "WebBrowser.super.removeNotify();" to look like this :- try { eventThread.interrupt(); WebBrowser.this.getPeer().destroyBuffers(); WebBrowser.this.getPeer().dispose(); WebBrowser.super.removeNotify(); } catch(Exception e) {} In org.jdesktop.jdic.browser.NativeEventThread.java, change the main event loop's ( line 112 ) try/catch block to look like this :- try { Thread.sleep(1); } catch (Exception e) { try {nativeBrowser.getInputStream().close();} catch(Exception e1){} try {nativeBrowser.getErrorStream().close();} catch(Exception e1){} try {nativeBrowser.getOutputStream().close();} catch(Exception e1){} processEvents(); try {messenger.portListening();} catch(Exception ex){} processIncomingMessage(messenger.getMessage()); nativeBrowser.destroy(); return; } Now any JFrame that includes a WebBrowser object will dispose correctly.
        Hide
        cknight19 added a comment -

        **NOTE

        You also need to remove the debug code from class
        org.jdesktop.jdic.browser.internal.NativeEventThread.java in inner class
        StreamGobbler, from its run method, basic make the run method blank.

        Show
        cknight19 added a comment - **NOTE You also need to remove the debug code from class org.jdesktop.jdic.browser.internal.NativeEventThread.java in inner class StreamGobbler, from its run method, basic make the run method blank.

          People

          • Assignee:
            laux
            Reporter:
            cknight19
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: