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

Cannot execute JavaScript when multiple WebViews are used at the same time

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P3 P3
    • 9
    • 8u45
    • javafx
    • web
    • x86_64
    • windows_7

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      We have a Swing-Application which we are trying to enhance with some JavaFX-Webviews to display Webpages. We need to communicate between Swing and the Webpage. We are using JavaScript to send data from Swing to the Webpage. This works fine as long we are only using one Webpage. Once we add a second Webpage we get error messages like this one "ReferenceError: Can't find variable: changeHtml".

      We are using a ChangeListener on the LoadWorker of a WebEngine to find out once if a page is loaded completely. But this does not work because for our failing webpages the states are
      READ -> SUCCEEDED (the JavaScript files are not loaded here)
      SUCCEEDED -> SCHEDULED
      SCHEDULED -> RUNNING (this is where the page is actually loaded completely)

      I was able to reproduce this with only JavaFX when using Platform.runLater to add multiple webpages. When not using Platform.runLater it works.
      We are using Platform.runLater in Swing because we are adding webviews to different tabs.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      - Create an application.
      - Add two WebViews with Platform.runLater
      - Add a ChangeListener to each LoadWorker
      - Execute JavaScript in an external js-File of the HTML-Page when the new-state is SUCCEEDED


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The JavaScript should be executed. In the sample application below both WebPages should change it's text and change it;s color.
      ACTUAL -
       ReferenceError: Can't find variable: XYZ

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "JavaFX Application Thread" netscape.javascript.JSException: ReferenceError: Can't find variable: changeHtml
      at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
      at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
      at com.sun.webkit.WebPage.executeScript(WebPage.java:1427)
      at javafx.scene.web.WebEngine.executeScript(WebEngine.java:948)
      at javafxbug.MyApplication$3.changed(MyApplication.java:57)
      at javafxbug.MyApplication$3.changed(MyApplication.java:1)
      at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
      at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
      at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
      at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
      at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
      at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
      at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1226)
      at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1337)
      at javafx.scene.web.WebEngine$LoadWorker.access$1100(WebEngine.java:1219)
      at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1206)
      at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2388)
      at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2232)
      at com.sun.webkit.network.URLLoader.twkDidFinishLoading(Native Method)
      at com.sun.webkit.network.URLLoader.notifyDidFinishLoading(URLLoader.java:830)
      at com.sun.webkit.network.URLLoader.lambda$didFinishLoading$95(URLLoader.java:821)
      at com.sun.webkit.network.URLLoader$$Lambda$117/1700372441.run(Unknown Source)
      at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
      at com.sun.javafx.application.PlatformImpl$$Lambda$48/349422632.run(Unknown Source)
      at java.security.AccessController.doPrivileged(Native Method)
      at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
      at com.sun.javafx.application.PlatformImpl$$Lambda$47/237061348.run(Unknown Source)
      at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
      at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
      at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
      at java.lang.Thread.run(Thread.java:745)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      MyApplication.java

      package javafxbug;

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.concurrent.Worker.State;
      import javafx.scene.Scene;
      import javafx.scene.layout.FlowPane;
      import javafx.scene.web.WebEngine;
      import javafx.scene.web.WebView;
      import javafx.stage.Stage;

      public class MyApplication extends Application {

      public static void main(String[] args) {
      launch();
      }

      @Override
      public void start(Stage stage) throws Exception {
      FlowPane pane = new FlowPane();
      Scene scene = new Scene(pane);
      Platform.runLater(new Runnable() {

      @Override
      public void run() {
      WebView webview1 = createWebview(getClass().getResource("/test.html").toExternalForm());
      pane.getChildren().add(webview1);

      }
      });
      Platform.runLater(new Runnable() {

      @Override
      public void run() {
      WebView webview2 = createWebview(getClass().getResource("/test.html").toExternalForm());
      pane.getChildren().add(webview2);
      }
      });
      stage.setScene(scene);
      stage.show();
      }

      private WebView createWebview(String url) {
      WebView webview = new WebView();
      final WebEngine webEngine = webview.getEngine();
      webEngine.load(url);
      webview.setPrefHeight(300);
      webview.setPrefWidth(5300);
      webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {

      @Override
      public void changed(ObservableValue<? extends State> arg0, State arg1, State arg2) {
      System.out.println("OldValue " + arg1 + " , Newvalue " + arg2);
      if (arg2.equals(State.SUCCEEDED))
      webEngine.executeScript("changeHtml();");
      }
      });
      return webview;
      }

      }


      -------
      test.html

      <html>
      <body>
      <script type="text/javascript" src="test.js"></script>
      <div id="test" style="background-color: red;">Before javascript</div>
      </body>
      </html>

      -------
      test.js

      function changeHtml() {
      var divToBeChanged = document.getElementById('test');
      divToBeChanged.innerHTML='After Javascript';
      divToBeChanged.style.backgroundColor='green';
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Run the JavaScript function if the state is SUCCEEDED or the State is RUNNING. Catch exceptions if the JavaScript-Name is not known.

            asrivastava Ankit Srivastava
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: