Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8227829

MacOS- AWT-EventQueue thread lock running WebView in JFXPanel

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: openjfx11, openjfx12
    • Fix Version/s: None
    • Component/s: javafx
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      os_x

      Description

      ADDITIONAL SYSTEM INFORMATION :
      Found the problem using:

      Mac OS Mojave version 10.14.5
      Java OpenJDK 12.0.1 and OpenJDK 11
      JavaFX 12.0.1 and JavaFX 11



      A DESCRIPTION OF THE PROBLEM :
      I have a locking problem with my Java application on MacOS where I am using the WebView in a Java Swing application. I am wrapping the WebView within the JFXPanel. The problem occurs when I switch focus from one my Swing Application to another window and then regain focus to my Swing Application.

      It then appears to lock and it appears that the AWT-EventThread is waiting within a FutureTask:

      Unsafe.park(boolean, long) line: not available [native method]

      LockSupport.park(Object) line: 194
      FutureTask<V>.awaitDone(boolean, long) line: 447
      FutureTask<V>.get() line: 190
      InputMethodClientlmpl.getTextLocation(int) line: 137
      SceneSInputMethodRequestsDelegate.getTextLocation(int) line: 4117
      InputMethodSupportSInputMethodRequestsAdapter.getTextLocation(TextHitInfo) line: 61
      InputMethodContext.getTextLocation(TextHitInfo) line: 278
      ClInputMethod$6.run(Q line: 722
      InvocationEvent.dispatch() line: 303
      EventQueue.dispatchEventlmpl(AWTEvent, Object) line: 770
      EventQueue$4.run( line: 721
      EventQueue$4.run() line: 715
      AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 750
      AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 389
      ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) li:
      ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext) line: 95
      EventQueue$5.runQ) line: 745
      EventQueue$5.run(Q line: 743
      AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 750
      AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 389
      ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) lit
      EventQueue.dispatchEvent(AWTEvent) line: 742
      EventDispatchThread.pumpOneEventForFilters(int) line: 203
      EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 124
      EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 113 v


      I cannot do anything else with the application.

      I have only found this problem on Mac OS and I cannot replicate it in Linux or Windows OS.

      I have only noticed this problem when losing focus form the application and regaining focus. Otherwise the WebView works as expected.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Reproduced by implementing the example SimpleSwingBrowser example from Oracle:

      https://docs.oracle.com/javafx/2/swing/SimpleSwingBrowser.java.htm

      Run the Swing application on the MacOS and lose focus to another window on the mac.. e.g TextEdit or Safari.

      Regaining focus back the the Swing Application it just hangs and you cannot click on anything or do anything.

      My application does exactly the same, but this simple example replicates my problem.

      Note that Windows and Linux work perfectly well.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Can click on the browser and follow links.
      ACTUAL -
      The application is locked and I cannot press on any links and the busy cursor is shown. The application never resolves itself.

      ---------- BEGIN SOURCE ----------
      import javafx.application.Platform;
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.embed.swing.JFXPanel;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.web.WebEngine;
      import javafx.scene.web.WebEvent;
      import javafx.scene.web.WebView;
       
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.*;
      import java.net.MalformedURLException;
      import java.net.URL;
       
      import static javafx.concurrent.Worker.State.FAILED;
        
      public class SimpleSwingBrowser extends JFrame {
       
          private final JFXPanel jfxPanel = new JFXPanel();
          private WebEngine engine;
       
          private final JPanel panel = new JPanel(new BorderLayout());
          private final JLabel lblStatus = new JLabel();


          private final JButton btnGo = new JButton("Go");
          private final JTextField txtURL = new JTextField();
          private final JProgressBar progressBar = new JProgressBar();
       
          public SimpleSwingBrowser() {
              super();
              initComponents();
          }

          
          private void initComponents() {
              createScene();
       
              ActionListener al = new ActionListener() {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      loadURL(txtURL.getText());
                  }
              };
       
              btnGo.addActionListener(al);
              txtURL.addActionListener(al);
        
              progressBar.setPreferredSize(new Dimension(150, 18));
              progressBar.setStringPainted(true);
        
              JPanel topBar = new JPanel(new BorderLayout(5, 0));
              topBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
              topBar.add(txtURL, BorderLayout.CENTER);
              topBar.add(btnGo, BorderLayout.EAST);
       
              JPanel statusBar = new JPanel(new BorderLayout(5, 0));
              statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
              statusBar.add(lblStatus, BorderLayout.CENTER);
              statusBar.add(progressBar, BorderLayout.EAST);
       
              panel.add(topBar, BorderLayout.NORTH);
              panel.add(jfxPanel, BorderLayout.CENTER);
              panel.add(statusBar, BorderLayout.SOUTH);
              
              getContentPane().add(panel);
              
              setPreferredSize(new Dimension(1024, 600));
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              pack();

          }
       
          private void createScene() {
       
              Platform.runLater(new Runnable() {
                  @Override
                  public void run() {
       
                      WebView view = new WebView();
                      engine = view.getEngine();
       
                      engine.titleProperty().addListener(new ChangeListener<String>() {
                          @Override
                          public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
                              SwingUtilities.invokeLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      SimpleSwingBrowser.this.setTitle(newValue);
                                  }
                              });
                          }
                      });
       
                      engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
                          @Override
                          public void handle(final WebEvent<String> event) {
                              SwingUtilities.invokeLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      lblStatus.setText(event.getData());
                                  }
                              });
                          }
                      });
       
                      engine.locationProperty().addListener(new ChangeListener<String>() {
                          @Override
                          public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
                              SwingUtilities.invokeLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      txtURL.setText(newValue);
                                  }
                              });
                          }
                      });
       
                      engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
                          @Override
                          public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) {
                              SwingUtilities.invokeLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      progressBar.setValue(newValue.intValue());
                                  }
                              });
                          }
                      });

                      engine.getLoadWorker()
                              .exceptionProperty()
                              .addListener(new ChangeListener<Throwable>() {
       
                                  public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) {
                                      if (engine.getLoadWorker().getState() == FAILED) {
                                          SwingUtilities.invokeLater(new Runnable() {
                                              @Override public void run() {
                                                  JOptionPane.showMessageDialog(
                                                          panel,
                                                          (value != null) ?
                                                          engine.getLocation() + "\n" + value.getMessage() :
                                                          engine.getLocation() + "\nUnexpected error.",
                                                          "Loading error...",
                                                          JOptionPane.ERROR_MESSAGE);
                                              }
                                          });
                                      }
                                  }
                              });

                      jfxPanel.setScene(new Scene(view));
                  }
              });
          }
       
          public void loadURL(final String url) {
              Platform.runLater(new Runnable() {
                  @Override
                  public void run() {
                      String tmp = toURL(url);
       
                      if (tmp == null) {
                          tmp = toURL("http://" + url);
                      }
       
                      engine.load(tmp);
                  }
              });
          }

          private static String toURL(String str) {
              try {
                  return new URL(str).toExternalForm();
              } catch (MalformedURLException exception) {
                      return null;
              }
          }

         

          public static void main(String[] args) {
              SwingUtilities.invokeLater(new Runnable() {

                  public void run() {
                      SimpleSwingBrowser browser = new SimpleSwingBrowser();
                      browser.setVisible(true);
                      browser.loadURL("http://oracle.com");
                 }
             });
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: