-
Bug
-
Resolution: Unresolved
-
P4
-
jfx11, jfx20, 8, jfx17, jfx19, jfx21
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Windows 10 21H2, jdk-8u251, IntelliJ 2020.2 Ultimate version as the IDE
A DESCRIPTION OF THE PROBLEM :
There are some report (JDK-8095034) (JDK-8298104) points this issue, but there are no simple examples to reproduce this results. I would like to provide an example to show how non-FX thread modify the FX components without triggering the IllegalStateException ("Not on FX application thread").
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the example source code with Java 1.8.0_251. (I am using IntelliJ 2020.2 Ultimate version as the IDE)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The IllegalStateException ("Not on FX application thread") is expected to be triggered (or if this is safe, the program should run without any exceptions)
ACTUAL -
Nullpointerexception is triggered after waiting for several seconds:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes(Scene.java:2289)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2419)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:398)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:397)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:424)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:561)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:541)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:534)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:340)
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$4(WinApplication.java:186)
at java.lang.Thread.run(Thread.java:748)
Or in some cases, ArrayIndexOutofBoundsException is triggered:
Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:422)
at java.util.ArrayList.get(ArrayList.java:435)
at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
at javafx.scene.Parent.updateCachedBounds(Parent.java:1591)
at javafx.scene.Parent.recomputeBounds(Parent.java:1535)
at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388)
at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078)
at javafx.scene.Node.updateGeomBounds(Node.java:3577)
at javafx.scene.Node.getGeomBounds(Node.java:3530)
at javafx.scene.Node.getLocalBounds(Node.java:3478)
at javafx.scene.Node.updateTxBounds(Node.java:3641)
at javafx.scene.Node.getTransformedBounds(Node.java:3424)
at javafx.scene.Node.updateBounds(Node.java:559)
at javafx.scene.Parent.updateBounds(Parent.java:1719)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2404)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:398)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:397)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:424)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:561)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:541)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:534)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:340)
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$4(WinApplication.java:186)
at java.lang.Thread.run(Thread.java:748)
---------- BEGIN SOURCE ----------
Main File:
package sample;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
FXMLLoader fxmlLoader;
@Override
public void start(Stage primaryStage) throws Exception{
fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = fxmlLoader.load();
Controller controller = fxmlLoader.getController();
controller.configureBinding();
controller.setupTimer();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller File:
package sample;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import java.util.Timer;
import java.util.TimerTask;
public class Controller {
@FXML
private Label label_test;
@FXML
private Label label_test1;
@FXML
private Label label_test2;
@FXML
private Label label_test3;
@FXML
private Label label_test4;
@FXML
private Label label_test5;
@FXML
private Label label_test6;
@FXML
private Label label_test7;
@FXML
private Label label_test8;
@FXML
private Label label_test9;
private Timer timer;
private Timer timer2;
private int test = 0;
private int test2 = 0;
private final SimpleStringProperty simpleStringProperty = new SimpleStringProperty();
public void configureBinding(){
simpleStringProperty.addListener((observable, oldValue, newValue) -> {
if (simpleStringProperty.get().equals("1")){
label_test.setVisible(true);
label_test.setDisable(false);
label_test1.setVisible(true);
label_test1.setDisable(false);
label_test2.setVisible(true);
label_test2.setDisable(false);
label_test3.setVisible(true);
label_test3.setDisable(false);
label_test4.setVisible(true);
label_test4.setDisable(false);
label_test5.setVisible(true);
label_test5.setDisable(false);
label_test6.setVisible(true);
label_test6.setDisable(false);
label_test7.setVisible(true);
label_test7.setDisable(false);
label_test8.setVisible(true);
label_test8.setDisable(false);
label_test9.setVisible(true);
label_test9.setDisable(false);
}else{
label_test.setVisible(false);
label_test.setDisable(true);
label_test1.setVisible(false);
label_test1.setDisable(true);
label_test2.setVisible(false);
label_test2.setDisable(true);
label_test3.setVisible(false);
label_test3.setDisable(true);
label_test4.setVisible(false);
label_test4.setDisable(true);
label_test5.setVisible(false);
label_test5.setDisable(true);
label_test6.setVisible(false);
label_test6.setDisable(true);
label_test7.setVisible(false);
label_test7.setDisable(true);
label_test8.setVisible(false);
label_test8.setDisable(true);
label_test9.setVisible(false);
label_test9.setDisable(true);
}
});
}
public void setupTimer(){
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
simpleStringProperty.set(test + "");
test = (test + 1) % 2;
}
}, 0, 1);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Label fx:id="label_test" text="Label" />
<Label fx:id="label_test1" text="Label" />
<Label fx:id="label_test2" text="Label" />
<Label fx:id="label_test3" text="Label" />
<Label fx:id="label_test4" text="Label" />
<Label fx:id="label_test5" text="Label" />
<Label fx:id="label_test6" text="Label" />
<Label fx:id="label_test7" text="Label" />
<Label fx:id="label_test8" text="Label" />
<Label fx:id="label_test9" text="Label" />
</children>
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
</GridPane>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Move the code that may modify JavaFX components into Platform.runLater().
FREQUENCY : occasionally
Windows 10 21H2, jdk-8u251, IntelliJ 2020.2 Ultimate version as the IDE
A DESCRIPTION OF THE PROBLEM :
There are some report (
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the example source code with Java 1.8.0_251. (I am using IntelliJ 2020.2 Ultimate version as the IDE)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The IllegalStateException ("Not on FX application thread") is expected to be triggered (or if this is safe, the program should run without any exceptions)
ACTUAL -
Nullpointerexception is triggered after waiting for several seconds:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes(Scene.java:2289)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2419)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:398)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:397)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:424)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:561)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:541)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:534)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:340)
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$4(WinApplication.java:186)
at java.lang.Thread.run(Thread.java:748)
Or in some cases, ArrayIndexOutofBoundsException is triggered:
Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:422)
at java.util.ArrayList.get(ArrayList.java:435)
at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
at javafx.scene.Parent.updateCachedBounds(Parent.java:1591)
at javafx.scene.Parent.recomputeBounds(Parent.java:1535)
at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388)
at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078)
at javafx.scene.Node.updateGeomBounds(Node.java:3577)
at javafx.scene.Node.getGeomBounds(Node.java:3530)
at javafx.scene.Node.getLocalBounds(Node.java:3478)
at javafx.scene.Node.updateTxBounds(Node.java:3641)
at javafx.scene.Node.getTransformedBounds(Node.java:3424)
at javafx.scene.Node.updateBounds(Node.java:559)
at javafx.scene.Parent.updateBounds(Parent.java:1719)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2404)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:398)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:397)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:424)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:561)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:541)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:534)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:340)
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$4(WinApplication.java:186)
at java.lang.Thread.run(Thread.java:748)
---------- BEGIN SOURCE ----------
Main File:
package sample;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
FXMLLoader fxmlLoader;
@Override
public void start(Stage primaryStage) throws Exception{
fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = fxmlLoader.load();
Controller controller = fxmlLoader.getController();
controller.configureBinding();
controller.setupTimer();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller File:
package sample;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import java.util.Timer;
import java.util.TimerTask;
public class Controller {
@FXML
private Label label_test;
@FXML
private Label label_test1;
@FXML
private Label label_test2;
@FXML
private Label label_test3;
@FXML
private Label label_test4;
@FXML
private Label label_test5;
@FXML
private Label label_test6;
@FXML
private Label label_test7;
@FXML
private Label label_test8;
@FXML
private Label label_test9;
private Timer timer;
private Timer timer2;
private int test = 0;
private int test2 = 0;
private final SimpleStringProperty simpleStringProperty = new SimpleStringProperty();
public void configureBinding(){
simpleStringProperty.addListener((observable, oldValue, newValue) -> {
if (simpleStringProperty.get().equals("1")){
label_test.setVisible(true);
label_test.setDisable(false);
label_test1.setVisible(true);
label_test1.setDisable(false);
label_test2.setVisible(true);
label_test2.setDisable(false);
label_test3.setVisible(true);
label_test3.setDisable(false);
label_test4.setVisible(true);
label_test4.setDisable(false);
label_test5.setVisible(true);
label_test5.setDisable(false);
label_test6.setVisible(true);
label_test6.setDisable(false);
label_test7.setVisible(true);
label_test7.setDisable(false);
label_test8.setVisible(true);
label_test8.setDisable(false);
label_test9.setVisible(true);
label_test9.setDisable(false);
}else{
label_test.setVisible(false);
label_test.setDisable(true);
label_test1.setVisible(false);
label_test1.setDisable(true);
label_test2.setVisible(false);
label_test2.setDisable(true);
label_test3.setVisible(false);
label_test3.setDisable(true);
label_test4.setVisible(false);
label_test4.setDisable(true);
label_test5.setVisible(false);
label_test5.setDisable(true);
label_test6.setVisible(false);
label_test6.setDisable(true);
label_test7.setVisible(false);
label_test7.setDisable(true);
label_test8.setVisible(false);
label_test8.setDisable(true);
label_test9.setVisible(false);
label_test9.setDisable(true);
}
});
}
public void setupTimer(){
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
simpleStringProperty.set(test + "");
test = (test + 1) % 2;
}
}, 0, 1);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Label fx:id="label_test" text="Label" />
<Label fx:id="label_test1" text="Label" />
<Label fx:id="label_test2" text="Label" />
<Label fx:id="label_test3" text="Label" />
<Label fx:id="label_test4" text="Label" />
<Label fx:id="label_test5" text="Label" />
<Label fx:id="label_test6" text="Label" />
<Label fx:id="label_test7" text="Label" />
<Label fx:id="label_test8" text="Label" />
<Label fx:id="label_test9" text="Label" />
</children>
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
</GridPane>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Move the code that may modify JavaFX components into Platform.runLater().
FREQUENCY : occasionally
- relates to
-
JDK-8298104 NPE on synchronizeSceneNodes()
- Open
-
JDK-8095034 NullPointerException at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes
- Closed