2011-01-08 41 views
1

我想創建一個測試類來打開一個JFrame。爲了阻止窗口關閉主線程完成的時刻,我添加了代碼以在另一個線程中打開窗口。我每次運行該應用程序我得到以下異常:嘗試在另一個線程中打開JFrame時,java.lang.ExceptionInInitializerError錯誤的原因和解決方法是什麼?

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

我想不通爲什麼,我發現了問題。

+0

重新格式化的代碼;如果不正確請回復。 – trashgod 2011-01-08 02:55:07

回答

1

異常消息告訴你到底發生了什麼問題:你正試圖在JVM關閉時創建一個新線程。

當主線程完成時JVM關閉的原因是因爲您在事件線程上調用了setDaemon(true)。刪除該行,只要該線程處於活動狀態,JVM就會保持運行狀態。

+0

我評論了setDaemon代碼,我仍然得到這個異常。 – user305801 2011-01-08 01:14:32

+0

好吧,很難看到發生了什麼,你能否修正你的問題的格式。無論如何,試圖通過在已經關閉的情況下啓動一個新線程來保存JVM是一種非常奇怪的方法:-) – 2011-01-08 01:19:59

0

當您嘗試將線程設置爲守護程序(true)時,會出現該問題。當您退出應用程序線程不能停止,從而引發java.lang.IllegalStateException: Shutdown in progress

,當你走了過來這個問題,你必須明確地告訴運行時仍要關閉線程,通過添加shotdownhook。

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

    Runtime.getRuntime().addShutdownHook(t);//explicit! 
    t.start(); 
    t.setDaemon(true); 
}