尝试在另一个线程中打开 JFrame 时出现 java.lang.ExceptionInInitializerError 错误的原因和解决方法是什么?

2022-01-24 00:00:00 java swing jframe

我正在尝试创建一个测试类来打开一个 JFrame.为了在主线程完成时停止窗口关闭,我添加了代码以在另一个线程中打开窗口.每次运行应用程序时,都会出现以下异常:

<上一页>线程测试线程"中的异常 java.lang.ExceptionInInitializerError在 java.lang.Runtime.addShutdownHook(Runtime.java:192)在 java.util.logging.LogManager.(LogManager.java:237)在 java.util.logging.LogManager$1.run(LogManager.java:177)在 java.security.AccessController.doPrivileged(本机方法)在 java.util.logging.LogManager.(LogManager.java:158)在 java.util.logging.Logger.getLogger(Logger.java:273)在 java.awt.Component.(Component.java:173)在反射器.ApplicationRunner.startObjectsPool(ApplicationRunner.java:18)在反射器.ReflectorEndToEndTest$1.run(ReflectorEndToEndTest.java:20)原因:java.lang.IllegalStateException:正在关闭在 java.lang.Shutdown.add(Shutdown.java:62)在 java.lang.ApplicationShutdownHooks.(ApplicationShutdownHooks.java:21)... 9 更多

代码如下:

@Test公共无效createIntegerClass()抛出异常{线程 t = new Thread("测试线程") {@覆盖公共无效运行(){尝试 {application.startObjectsPool();} 捕捉(异常 e){e.printStackTrace();}}};t.start();t.setDaemon(true);}公共类 ApplicationRunner {公共最终静态字符串 [] NO_ARGS = null;公共无效 startObjectsPool() 抛出异常 {ObjectsPoolFrame frame = new ObjectsPoolFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}公共对象池框架(){setTitle("对象池");//获取屏幕尺寸工具包套件 = Toolkit.getDefaultToolkit();尺寸 screenSize = kit.getScreenSize();int screenHeight = screenSize.height;int screenWidth = screenSize.width;//屏幕中心框setSize(screenWidth/2, screenHeight/2);setLocation(screenWidth/4, screenHeight/4);op = 新的对象池();//在顶部添加按钮j1 = new JButton("创建对象");j2 = new JButton("删除对象");j3 = new JButton("显示方法");j4 = new JButton("调用方法");JPanel buttonPanel = new JPanel();buttonPanel.add(j1);buttonPanel.add(j2);buttonPanel.add(j3);buttonPanel.add(j4);添加(按钮面板,BorderLayout.NORTH);j1.addActionListener(new CreateObjectAction());j2.addActionListener(new DeleteObjectAction());j3.addActionListener(new DisplayMethodAction());j4.addActionListener(new InvokeMethodAction());组合框 = 新的 JComboBox();comboBox.addActionListener(new ComboBoxClearAction());addComboBoxItem();组合框2 = 新的 JComboBox();JPanel 组合面板 = 新 JPanel();comboPanel.add(new JLabel("Objects"));组合面板.add(组合框);comboPanel.add(new JLabel("方法"));comboPanel.add(comboBox2);添加(组合面板,BorderLayout.CENTER);displayMessage = new JLabel();JPanel displayPanel = new JPanel();displayPanel.add(displayMessage);添加(显示面板,BorderLayout.SOUTH);设置默认关闭操作(JFrame.EXIT_ON_CLOSE);设置可见(真);}

我不知道为什么会出现这个问题.

解决方案

异常消息告诉你到底出了什么问题:你试图在 JVM 关闭时创建一个新线程.

JVM 在主线程完成时关闭的原因是因为您在事件线程上调用了 setDaemon(true).删除该行,只要该线程处于活动状态,JVM 就会一直运行.

I'm trying to creating a test class to open a JFrame. In order to stop the window from closing the moment the main thread finishes I added the code to open up the window in another thread. Every time I run the application I get the following exception:

Exception in thread "Test Thread" java.lang.ExceptionInInitializerError
    at java.lang.Runtime.addShutdownHook(Runtime.java:192)
    at java.util.logging.LogManager.(LogManager.java:237)
    at java.util.logging.LogManager$1.run(LogManager.java:177)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.util.logging.LogManager.(LogManager.java:158)
    at java.util.logging.Logger.getLogger(Logger.java:273)
    at java.awt.Component.(Component.java:173)
    at reflector.ApplicationRunner.startObjectsPool(ApplicationRunner.java:18)
    at reflector.ReflectorEndToEndTest$1.run(ReflectorEndToEndTest.java:20)
Caused by: java.lang.IllegalStateException: Shutdown in progress
    at java.lang.Shutdown.add(Shutdown.java:62)
    at java.lang.ApplicationShutdownHooks.(ApplicationShutdownHooks.java:21)
... 9 more

The code is below:

@Test
public void createIntegerClass() throws Exception {
    Thread t = new Thread("Test Thread") {
        @Override
        public void run() {
            try {
                application.startObjectsPool();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    t.start();
    t.setDaemon(true);
}

public class ApplicationRunner {

    public final static String[] NO_ARGS = null;

    public void startObjectsPool() throws Exception {

        ObjectsPoolFrame frame = new ObjectsPoolFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

public ObjectsPoolFrame() {
    setTitle("Objects Pool");

    // get screen dimension
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenHeight = screenSize.height;
    int screenWidth = screenSize.width;

    // center frame in screen
    setSize(screenWidth / 2, screenHeight / 2);
    setLocation(screenWidth / 4, screenHeight / 4);

    op = new ObjectPool();

    // add buttons on the top
    j1 = new JButton("Create Object");
    j2 = new JButton("Delete Object");
    j3 = new JButton("Display Methods");
    j4 = new JButton("Invoke Method");
    JPanel buttonPanel = new JPanel();
    buttonPanel.add(j1);
    buttonPanel.add(j2);
    buttonPanel.add(j3);
    buttonPanel.add(j4);
    add(buttonPanel, BorderLayout.NORTH);
    j1.addActionListener(new CreateObjectAction());
    j2.addActionListener(new DeleteObjectAction());
    j3.addActionListener(new DisplayMethodAction());
    j4.addActionListener(new InvokeMethodAction());

    comboBox = new JComboBox();
    comboBox.addActionListener(new ComboBoxClearAction());
    addComboBoxItem();

    comboBox2 = new JComboBox();

    JPanel comboPanel = new JPanel();
    comboPanel.add(new JLabel("Objects"));
    comboPanel.add(comboBox);

    comboPanel.add(new JLabel("Methods"));
    comboPanel.add(comboBox2);
    add(comboPanel, BorderLayout.CENTER);

    displayMessage = new JLabel();
    JPanel displayPanel = new JPanel();
    displayPanel.add(displayMessage);
    add(displayPanel, BorderLayout.SOUTH);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

I can't figure why I'm getting the issue.

解决方案

The exception message tells you exactly what is wrong: you're trying to create a new thread while the JVM is shutting down.

The reason the JVM shuts down when the main thread finishes is because you call setDaemon(true) on your event thread. Remove that line and the JVM will stay up as long as that thread is alive.

相关文章