java - 在文本字段中按 Enter 键时 JVM 崩溃

标签 java jvm javafx

我有一个 JavaFx 程序,其行为非常不稳定。

如果我在文本字段上按 Enter 键,JVM 就会崩溃。这是从 this stackoverflow 问题中获得的一个简单的 UI 程序。这个看似无辜的程序有什么问题吗?

我正在运行 Lubuntu 12.10JDK 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;
                }
        }
}

转储的某些部分 -

#
# 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
#

完整的转储可用 here

编辑 1:

使用最新版本的 Oracle Java 1.7.0_25-b15 运行它也会崩溃。

编辑2:

使用OpenJDK 7u9-2.3.4-0ubuntu1.12.10.1运行它不会崩溃,但会出现以下错误 -

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

最佳答案

在我看来,原生 UI 代码中存在潜在的线程错误 - 在带有最新 JDK 的 Windows 7 x64 上,它运行时没有出现问题(目前无法访问 Linux 计算机进行测试。)

我之前见过类似的奇怪行为,其中 UI 代码被从平台线程中调用,但据我所知,这里没有发生这种情况。话虽如此,尽管您不必这样做(因为无论如何它都在平台线程上),但我有时发现将有问题的代码片段包装在 Platform.runLater() 中无论如何都可以解决问题 - 或者至少解决它:

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

这可能只是以 GTK 恰好喜欢的方式改变线程,尽管这并不理想。无论哪种方式,都值得尽可能地简化示例(同时您仍然可靠地得到错误)并报告错误。

关于java - 在文本字段中按 Enter 键时 JVM 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18512654/

相关文章:

Java 正则表达式

java - Jar 可执行文件但找不到主类的类路径

java - HotSpot 堆栈防护页。红色/黄色区域及其背后的原因

java - 在 jnlp 文件上传递参数

javafx tableview仅在排序后更新数据

java - 如何测试树项是否是javafx中 TreeView 的根节点?

java - StringBuffer.append() 与 ArrayList<String>.add()

java - XSD 架构中需要什么来生成 @XmlElementDecl 方法?

java - xp 和 window 7 的 jvm 内存分配策略不同

java - 使用额外的第三方插件运行 kafka 服务器,用于统计数据收集、日志记录等