2

I have a JavaFx program that is behaving very erratically.

If I press enter on a textfield the JVM crashes. This is a simple UI program obtained from this stackoverflow question. What is wrong with this innocent looking program?

I am running Lubuntu 12.10 and JDK 1.7.0_09-b05.

import com.sun.glass.events.KeyEvent;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;

public class MissingDataDemo extends Application {
        private static final String[] SAMPLE_TEXT = "Lorem ipsum MISSING dolor sit amet MISSING consectetur adipisicing elit sed do eiusmod tempor incididunt MISSING ut labore et dolore magna aliqua"
                        .split(" ");

        @Override
        public void start(Stage primaryStage) {
                VBox textContainer = new VBox(10);
                textContainer
                                .setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");

                primaryStage.setScene(new Scene(textContainer, 300, 600));
                primaryStage.show();

                TextLoader textLoader = new TextLoader(SAMPLE_TEXT, textContainer);
                textLoader.loadText();
        }

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

class TextLoader {
        private final String[] lines;
        private final Pane container;

        TextLoader(final String[] lines, final Pane container) {
                this.lines = lines;
                this.container = container;
        }

        public void loadText() {
                for (String nextText : lines) {
                        final Label nextLabel = new Label();

                        if ("MISSING".equals(nextText)) {
                                nextLabel.setStyle("-fx-background-color: palegreen;");

                                MissingTextPrompt prompt = new MissingTextPrompt(container
                                                .getScene().getWindow());

                                nextText = prompt.getResult();
                        }

                        nextLabel.setText(nextText);

                        container.getChildren().add(nextLabel);
                }
        }

        class MissingTextPrompt {
                private final String result;

                MissingTextPrompt(Window owner) {
                        final Stage dialog = new Stage();

                        dialog.setTitle("Enter Missing Text");
                        dialog.initOwner(owner);
                        dialog.initStyle(StageStyle.UTILITY);
                        dialog.initModality(Modality.WINDOW_MODAL);
                        dialog.setX(owner.getX() + owner.getWidth());
                        dialog.setY(owner.getY());

                        final TextField textField = new TextField();
                        final Button submitButton = new Button("Submit");
                        submitButton.setDefaultButton(true);

                        submitButton.setOnAction(new EventHandler<ActionEvent>() {
                                @Override
                                public void handle(ActionEvent t) {
                                        dialog.close();
                                }
                        });

                        textField.setMinHeight(TextField.USE_PREF_SIZE);

                        final VBox layout = new VBox(10);
                        layout.setAlignment(Pos.CENTER_RIGHT);
                        layout.setStyle("-fx-background-color: azure; -fx-padding: 10;");
                        layout.getChildren().setAll(textField, submitButton);

                        dialog.setScene(new Scene(layout));
                        dialog.showAndWait();

                        result = textField.getText();
                }

                private String getResult() {
                        return result;
                }
        }
}

Some portion of the dump -

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb6cfa39f, pid=14093, tid=1803479872
#
# JRE version: 7.0_09-b05
# Java VM: Java HotSpot(TM) Server VM (23.5-b02 mixed mode linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x42539f]  jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x2f
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

The complete dump is available here.

Edit 1:

Running it with latest version of Oracle Java 1.7.0_25-b15 also crashes.

Edit 2:

Running it with OpenJDK 7u9-2.3.4-0ubuntu1.12.10.1 does not crash but gives following error -

Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
    at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
    at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.NullPointerException
    at com.sun.glass.ui.gtk.GtkApplication.enterNestedEventLoopImpl(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication._enterNestedEventLoop(GtkApplication.java:137)
    at com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:383)
    at com.sun.glass.ui.EventLoop.enter(EventLoop.java:83)
    at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:520)
    at javafx.stage.Stage.showAndWait(Stage.java:397)
    at com.mango.proengin.ui.user.TextLoader$MissingTextPrompt.<init>(MissingDataDemo.java:96)
    at com.mango.proengin.ui.user.TextLoader.loadText(MissingDataDemo.java:52)
    at com.mango.proengin.ui.user.MissingDataDemo.start(MissingDataDemo.java:28)
    at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
    at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:206)
    at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82)
    ... 1 more
Community
  • 1
  • 1
Kshitiz Sharma
  • 17,947
  • 26
  • 98
  • 169
  • There is a code tool in the editor, why do you link to pastebin? Paste the code here please. – BackSlash Aug 29 '13 at 13:46
  • Have you tried updating your JVM? Your JVM version looks pretty old. You can check the [Java 7 Update Release Notes](http://www.oracle.com/technetwork/java/javase/7u-relnotes-515228.html) page for the current version info. – DaoWen Aug 29 '13 at 13:48
  • @BackSlash The size of the code is large. Even more so the JVM dump which is 839 lines. – Kshitiz Sharma Aug 29 '13 at 13:51
  • @KshitizSharma Ok for the jvm dump, the code is not so large, i've seen larger codes posted here – BackSlash Aug 29 '13 at 13:52
  • 1
    That's not a JVM crash, that's an exception being thrown. There's a huge difference. – mikołak Aug 29 '13 at 14:05
  • @TheTerribleSwiftTomato Did you not see the JVM dump? – Kshitiz Sharma Aug 29 '13 at 14:08
  • @Daowen Using the latest version makes no difference. – Kshitiz Sharma Aug 29 '13 at 14:13
  • 1
    I can't see why this is being downvoted? Seems like a perfectly reasonable question to me. – Michael Berry Aug 29 '13 at 14:20
  • @KshitizSharma: I was referring to the stack trace you also posted. It pays to be precise in the question title, you'll get more of the right attention that way. And I'm sorry, but I'm a little strapped for time, so giving this advice is all I can spare at the moment. – mikołak Aug 29 '13 at 14:23

1 Answers1

3

Looks like a potential threading bug in native UI code to me - on Windows 7 x64 with the latest JDK it's running without an issue (don't have access to a Linux machine to test on at the moment.)

I've seen similar bizarre behaviour before where UI code has been called off the platform thread, though as far as I can make out that's not happening here. Having said that, and although you shouldn't have to (since it's on the platform thread anyway) I've sometimes found that wrapping the offending piece of code in a Platform.runLater() anyway can solve the issue - or at least work around it:

        submitButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        dialog.close();
                    }
                });
            }
        });

That may just change the threading in a way that GTK happens to like, though it's not ideal. Either way, could be worth simplifying the example down as much as you can (while you still reliably get the error) and reporting the bug.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216