Какова причина и разрешение ошибки java.lang.ExceptionInInitializerError при попытке открыть JFrame в другом потоке? - PullRequest
1 голос
/ 08 января 2011

Я пытаюсь создать тестовый класс для открытия JFrame. Чтобы остановить закрытие окна в момент завершения основного потока, я добавил код, чтобы открыть окно в другом потоке. Каждый раз, когда я запускаю приложение, я получаю следующее исключение:

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

Код ниже:

@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);
}

Я не могу понять, почему у меня проблема.

Ответы [ 2 ]

1 голос
/ 08 января 2011

Сообщение об исключительной ситуации точно говорит вам, что не так: вы пытаетесь создать новый поток, пока JVM завершает работу.

Причина, по которой JVM завершает работу после завершения основного потока, заключается в том, что вы вызываете setDaemon(true) в потоке событий. Удалите эту строку, и JVM останется включенным, пока этот поток жив.

0 голосов
/ 17 марта 2016

проблема возникает при попытке установить Thread в Daemon (true).Когда вы выходите из приложения, поток не может быть остановлен и, следовательно, выдает java.lang.IllegalStateException: Shutdown in progress

, когда вы столкнулись с этой проблемой, вы должны явно сказать Runtime, чтобы закрыть поток в любом случае, добавивShootownhook.

public void createIntegerClass() throws Exception {
    Thread t = new Thread("Test Thread") {...};

    Runtime.getRuntime().addShutdownHook(t);//explicit!
    t.start();
    t.setDaemon(true);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...