FULL PRODUCT VERSION : java version "1.8.0_65" Java(TM) SE Runtime Environment (build 1.8.0_65-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode) ADDITIONAL OS VERSION INFORMATION : Linux linux-hj5y 3.11.10-29-desktop #1 SMP PREEMPT Thu Mar 5 16:24:00 UTC 2015 (338c513) x86_64 x86_64 x86_64 GNU/Linux A DESCRIPTION OF THE PROBLEM : I'm writing a connector for a solution written in JavaScript with a library written in Java. Several methods of this library are invoked from JavaScript scripts. When I invoke methods that have arguments java.lang.Double type, the argument values ������are being converted to null. If these methods use double native types as arguments , it works perfectly. I made a simple class to exemplify: public class SimpleJavaObject { private Double doubleAttribute = null; private final StringBuilder sbDebugText = new StringBuilder(); public SimpleJavaObject() { } public void setDoubleAttribute(Double doubleAttributeArgument) { debug("Double setter: "+doubleAttributeArgument); doubleAttribute = doubleAttributeArgument; } // public void setDoubleAttribute(double doubleAttributeArgument) { // debug("double setter: "+doubleAttributeArgument); // doubleAttribute = doubleAttributeArgument; // } // public void setDoubleAttribute(Object doubleAttributeArgument) { // debug("Object setter: "+doubleAttributeArgument); // doubleAttribute = (Double) doubleAttributeArgument; // } // public void setDoubleAttribute(String doubleAttributeArgument) { // debug("String setter: "+doubleAttributeArgument); // doubleAttribute = Double.valueOf(doubleAttributeArgument); // } public Double getDoubleAttribute() { return doubleAttribute; } private void debug(String str) { sbDebugText.append(str); sbDebugText.append("\n"); } public String getDebugText() { return sbDebugText.toString(); } } And a simple html page with one simple script: <!DOCTYPE html> <html> <head> <title>WebView tests</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript"> var simpleJavaObject = null; // setted from outside like jsWindow.setMember("simpleJavaObject", new SimpleJavaObject()); function test() { alert("simpleJavaObject: " + simpleJavaObject); // shows - simpleJavaObject: webviewtests.SimpleJavaObject@8abb96e simpleJavaObject.setDoubleAttribute(15.5); // try to change the attribute value alert("simpleJavaObject.getDoubleAttribute(): " + simpleJavaObject.getDoubleAttribute()); // shows - simpleJavaObject.getDoubleAttribute(): null alert("Test summary:\n"+simpleJavaObject.getDebugText()); // Shows - Test summary: // Double setter: null // indicating the setter invoked } </script> </head> <body> </body> </html> As I uncomment the overloaded setters (keeping commented the method with native double argument) I have the following precedence: - setDoubleAttribute(Object doubleAttributeArgument) - setDoubleAttribute(String doubleAttributeArgument) - setDoubleAttribute(Double doubleAttributeArgument) - with doubleAttributeArgument = null The question is: Why this method only works with native double, String and Object, and not work with java.lang.Double? Many thanks in advance for your attention. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Call any method with java.lang.Double or java.lang.Integer argument from html page using javascript inside a webview component. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Show the message with 15.5 value. ACTUAL - Show the message with null value. REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- // Create all classes and resources in the same package named webviewtests in a simple JavaFX project // Main class WebViewTests.java package webviewtests; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; /** * * @author Marcos Martinewski Alves */ public class WebViewTests extends Application { @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); Scene scene = new Scene(root); stage.setMaximized(true); stage.setScene(scene); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } // FXMLDocument.xml <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <StackPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="webviewtests.FXMLDocumentController"> <javafx.scene.web.WebView fx:id="webview"/> </StackPane> // FXMLDocumentController.java package webviewtests; import java.net.URL; import java.util.ResourceBundle; import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.web.WebErrorEvent; import javafx.scene.web.WebEvent; import javafx.scene.web.WebView; import javax.swing.JOptionPane; import netscape.javascript.JSObject; /** * * @author Marcos Martinewski Alves */ public class FXMLDocumentController implements Initializable { @FXML private WebView webview; @Override public void initialize(URL url, ResourceBundle rb) { initializeWebView(); loadTestPage(); } private void initializeWebView() { webview.getEngine().setOnAlert((WebEvent<String> event) -> { JOptionPane.showMessageDialog(null, event.getData()); }); webview.getEngine().setOnError((WebErrorEvent event) -> { event.getException().printStackTrace(System.err); }); webview.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) -> { if (Worker.State.SUCCEEDED.equals(newValue)) { initSimpleJavaObject(); } }); } private void loadTestPage() { webview.getEngine().load(getClass().getResource("test.html").toExternalForm()); } private void initSimpleJavaObject() { SimpleJavaObject simpleJavaObject = new SimpleJavaObject(); JSObject jsWindow = (JSObject) webview.getEngine().executeScript("window"); jsWindow.setMember("simpleJavaObject", simpleJavaObject); webview.getEngine().executeScript("test();"); } } // SimpleJavaObject.java package webviewtests; /** * * @author Marcos Martinewski Alves */ public class SimpleJavaObject { private Double doubleAttribute = null; private final StringBuilder sbDebugText = new StringBuilder(); public SimpleJavaObject() { } public void setDoubleAttribute(Double doubleAttributeArgument) { debug("Double setter: "+doubleAttributeArgument); doubleAttribute = doubleAttributeArgument; } // public void setDoubleAttribute(double doubleAttributeArgument) { // debug("double setter: "+doubleAttributeArgument); // doubleAttribute = doubleAttributeArgument; // } // public void setDoubleAttribute(Object doubleAttributeArgument) { // debug("Object setter: "+doubleAttributeArgument); // doubleAttribute = (Double) doubleAttributeArgument; // } // public void setDoubleAttribute(String doubleAttributeArgument) { // debug("String setter: "+doubleAttributeArgument); // doubleAttribute = Double.valueOf(doubleAttributeArgument); // } public Double getDoubleAttribute() { return doubleAttribute; } private void debug(String str) { sbDebugText.append(str); sbDebugText.append("\n"); } public String getDebugText() { return sbDebugText.toString(); } } // test.html <!DOCTYPE html> <html> <head> <title>WebView tests</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript"> var simpleJavaObject = null; function test() { alert("simpleJavaObject: " + simpleJavaObject); simpleJavaObject.setDoubleAttribute(15.5); alert("simpleJavaObject.getDoubleAttribute(): " + simpleJavaObject.getDoubleAttribute()); alert("Test summary:\n"+simpleJavaObject.getDebugText()); } </script> </head> <body> </body> </html> ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : There is a one workaround, reimplementing all methods that use java.lang.Double as arguments, to use native double, but this may imply in some alterations of expected behaviour of the app.
|