AW: WG: Minimal reproduction example for JDK-8217953 NPE in TableCellSkin
Peter, Benjamin
B.Peter at gsi.de
Fri Feb 14 07:22:11 UTC 2020
Hello Kevin,
sure, will do :-).
==== BEGIN ====
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
public class TableViewCellDisposeProblem extends Application {
public static class Person {
private StringProperty firstName;
public void setFirstName(String value) {
firstNameProperty().set(value);
}
public String getFirstName() {
return firstNameProperty().get();
}
public StringProperty firstNameProperty() {
if (firstName == null)
firstName = new SimpleStringProperty(this, "firstName");
return firstName;
}
private StringProperty lastName;
public void setLastName(String value) {
lastNameProperty().set(value);
}
public String getLastName() {
return lastNameProperty().get();
}
public StringProperty lastNameProperty() {
if (lastName == null)
lastName = new SimpleStringProperty(this, "lastName");
return lastName;
}
public Person(String firstName, String lastName) {
setFirstName(firstName);
setLastName(lastName);
}
}
private ObservableList<Person> teamMembers = FXCollections.observableArrayList( //
List.of( //
new Person("William", "Reed"), //
new Person("James", "Michaelson"), //
new Person("Julius", "Dean") //
));
TableView<Person> table = new TableView<>();
private AtomicInteger updateCount = new AtomicInteger();
public void updateLoop() {
Thread thread = new Thread(() -> {
while (true) {
System.out.println("updating i = "+ updateCount.incrementAndGet());
Platform.runLater(() -> {
// Trigger column visibility - Without this, no exception observed!
TableColumn<Person, ?> secondColumn = table.getColumns().get(1);
secondColumn.setVisible(!secondColumn.isVisible());
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("interrupted");
break;
}
}
});
thread.setDaemon(true);
thread.start();
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(table, 800, 600));
table.setItems(teamMembers);
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
table.getColumns().setAll(firstNameCol, lastNameCol);
primaryStage.show();
updateLoop();
}
public static void main(String[] args) {
Application.launch(args);
}
}
/*
* After 100 updates following Exception occurs (of 5 test runs, sleep time varied):
*
* [WARNING]
java.lang.NullPointerException
at javafx.scene.control.skin.TableCellSkin.tableColumnProperty (TableCellSkin.java:97)
at javafx.scene.control.skin.TableCellSkinBase.getTableColumn (TableCellSkinBase.java:123)
at javafx.scene.control.skin.TableCellSkinBase.dispose (TableCellSkinBase.java:136)
at javafx.scene.control.skin.TableCellSkin.dispose (TableCellSkin.java:88)
at javafx.scene.control.Control$2.invalidated (Control.java:267)
at javafx.beans.property.ObjectPropertyBase.markInvalid (ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set (ObjectPropertyBase.java:147)
at javafx.css.StyleableObjectProperty.set (StyleableObjectProperty.java:82)
at javafx.scene.control.Control$2.set (Control.java:250)
at javafx.scene.control.Control$2.set (Control.java:233)
at javafx.scene.control.Control.setSkin (Control.java:230)
at javafx.scene.control.skin.TableRowSkinBase.recreateCells (TableRowSkinBase.java:715)
at javafx.scene.control.skin.TableRowSkinBase.updateCells (TableRowSkinBase.java:505)
at javafx.scene.control.skin.TableRowSkinBase.checkState (TableRowSkinBase.java:649)
at javafx.scene.control.skin.TableRowSkinBase.computePrefHeight (TableRowSkinBase.java:588)
at javafx.scene.control.Control.computePrefHeight (Control.java:570)
at javafx.scene.Parent.prefHeight (Parent.java:1039)
at javafx.scene.layout.Region.prefHeight (Region.java:1559)
at javafx.scene.control.skin.VirtualFlow.resizeCell (VirtualFlow.java:1923)
at javafx.scene.control.skin.VirtualFlow.addLeadingCells (VirtualFlow.java:2030)
at javafx.scene.control.skin.VirtualFlow.layoutChildren (VirtualFlow.java:1250)
at javafx.scene.Parent.layout (Parent.java:1206)
at javafx.scene.Parent.layout (Parent.java:1213)
at javafx.scene.Scene.doLayoutPass (Scene.java:576)
at javafx.scene.Scene$ScenePulseListener.pulse (Scene.java:2482)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2 (Toolkit.java:412)
at java.security.AccessController.doPrivileged (Native Method)
at com.sun.javafx.tk.Toolkit.runPulse (Toolkit.java:411)
at com.sun.javafx.tk.Toolkit.firePulse (Toolkit.java:438)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse (QuantumToolkit.java:563)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse (QuantumToolkit.java:543)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue (QuantumToolkit.java:536)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11 (QuantumToolkit.java:342)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run (InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.gtk.GtkApplication._runLoop (Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11 (GtkApplication.java:277)
at java.lang.Thread.run (Thread.java:834)
updating
[WARNING]
java.lang.NullPointerException
at javafx.scene.control.skin.CellSkinBase$StyleableProperties$1.isSettable (CellSkinBase.java:166)
at javafx.scene.control.skin.CellSkinBase$StyleableProperties$1.isSettable (CellSkinBase.java:161)
at javafx.scene.CssStyleHelper.transitionToState (CssStyleHelper.java:666)
at javafx.scene.Node.doProcessCSS (Node.java:9658)
at javafx.scene.Node$1.doProcessCSS (Node.java:471)
at com.sun.javafx.scene.NodeHelper.processCSSImpl (NodeHelper.java:192)
at com.sun.javafx.scene.ParentHelper.superProcessCSSImpl (ParentHelper.java:93)
at com.sun.javafx.scene.ParentHelper.superProcessCSS (ParentHelper.java:63)
at javafx.scene.Parent.doProcessCSS (Parent.java:1368)
at javafx.scene.Parent$1.doProcessCSS (Parent.java:125)
at com.sun.javafx.scene.ParentHelper.processCSSImpl (ParentHelper.java:98)
at com.sun.javafx.scene.control.ControlHelper.superProcessCSSImpl (ControlHelper.java:63)
at com.sun.javafx.scene.control.ControlHelper.superProcessCSS (ControlHelper.java:55)
at javafx.scene.control.Control.doProcessCSS (Control.java:886)
at javafx.scene.control.Control$1.doProcessCSS (Control.java:89)
at com.sun.javafx.scene.control.ControlHelper.processCSSImpl (ControlHelper.java:67)
at com.sun.javafx.scene.NodeHelper.processCSS (NodeHelper.java:145)
at javafx.scene.Node.processCSS (Node.java:9540)
at javafx.scene.Node.processCSS (Node.java:9533)
at javafx.scene.Node.processCSS (Node.java:9533)
at javafx.scene.Node.processCSS (Node.java:9533)
at javafx.scene.Node.processCSS (Node.java:9533)
at javafx.scene.Node.processCSS (Node.java:9533)
at javafx.scene.Scene.doCSSPass (Scene.java:569)
at javafx.scene.Scene$ScenePulseListener.pulse (Scene.java:2477)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2 (Toolkit.java:412)
at java.security.AccessController.doPrivileged (Native Method)
at com.sun.javafx.tk.Toolkit.runPulse (Toolkit.java:411)
at com.sun.javafx.tk.Toolkit.firePulse (Toolkit.java:438)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse (QuantumToolkit.java:563)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse (QuantumToolkit.java:543)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue (QuantumToolkit.java:536)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11 (QuantumToolkit.java:342)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run (InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.gtk.GtkApplication._runLoop (Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11 (GtkApplication.java:277)
at java.lang.Thread.run (Thread.java:834)
updating
*/
===== END ====
best wishes,
Ben
> -----Ursprüngliche Nachricht-----
> Von: Kevin Rushforth <kevin.rushforth at oracle.com>
> Gesendet: Donnerstag, 13. Februar 2020 15:46
> An: Peter, Benjamin <B.Peter at gsi.de>; openjfx-dev at openjdk.java.net
> Betreff: Re: WG: Minimal reproduction example for JDK-8217953 NPE in
> TableCellSkin
>
> Unfortunately, attachments don't make it through the openjdk mailing list filters.
> Can you just paste it inline?
>
> Thanks.
>
> -- Kevin
>
>
> On 2/13/2020 6:02 AM, Peter, Benjamin wrote:
> > Hello devs,
> >
> > same example but with the file as attachment and without header.
> >
> >
> > regards,
> >
> > Ben
> >
> > -----Ursprüngliche Nachricht-----
> > Von: openjfx-dev <openjfx-dev-bounces at openjdk.java.net> Im Auftrag von
> > Peter, Benjamin
> > Gesendet: Donnerstag, 13. Februar 2020 11:54
> > An: openjfx-dev at openjdk.java.net
> > Betreff: Minimal reproduction example for JDK-8217953 NPE in
> > TableCellSkin
> >
> > Dear FX devs,
> >
> > please accept my minimal reproduction example for JDK-8217953
> "NullPointerException when TableCellSkin gets disposed twice"
> >
> > In the report it says there was no luck reproducing it - I hope this could now be
> beneficial for a solution to this problem.
> >
> > I could repeatedly trigger the problem after 100 of my update cycles - which
> interestingly corresponds to the following constant which can be found along the
> stacktrace.
> > javafx.scene.control.skin.TableRowSkinBase.DEFAULT_FULL_REFRESH_COUNTER
> = 100 Surely - could be coincidence - but also a hot lead.
> >
> >
> > I can also confirm it is still reproducable in jfx 11 and 13.
> >
> > It is available as public domain gist on github:
> >
> > https://gist.github.com/dedeibel/d02fb51c59942bebcb6e418f23d310fb
> >
> >
> >
> > Thank you for your work and cooperation,
> >
> > with kind regards,
> >
> >
> > Benjamin Peter
More information about the openjfx-dev
mailing list