2013-11-20 67 views
0

我有一個無頭運行的應用程序,需要能夠通知管理員有問題。我爲它建立了一個電子郵件通知框架,並且基本上如果拋出並捕獲到異常(取決於代碼中的區域和異常的重要性),它可能會傳遞到警報通知框架,從而觸發電子郵件外出通過堆棧跟蹤和其他調試信息與列出的管理員進行通信。拋出未處理的異常後卡住了線程

這工作,很好。

部署之前,我正在通過它的步伐。我的一個測試是從代碼中的隨機點拋出一個未處理的異常 - 模擬一個潛在的嚴重運行時問題,其中拋出了我們沒有預料到的異常。

例如,這裏是我插入測試未處理的異常的方法:

/** 
* Closes connection. 
*/ 
public void closeConnection() { 
    if (true) 
    throw new NullPointerException("Test unexpected exception NPE"); 
    LOG.info("Closing SFTP connection"); 
    getSftpChannel().exit(); 
    getSession().disconnect(); 
    LOG.debug("SFTP Connection closed"); 

} 

的代碼運行,並且當它到達這個未處理的異常,程序硬件鎖(因爲拋出異常,並且所述SFTP連接線程從不關閉,所以它保持jvm打開,直到連接超時)。

我原以爲會導致JVM崩潰,或者將它傳遞給它的調用者,最終會引發警報系統。

在這種情況下,我認爲這個NPE會拋出這個異常,不會由它的調用者或調用者的調用者等處理,所以它應該冒泡到main(),然後崩潰JVM,因爲甚至主要不抓Exception或NPE的。

Question:這裏發生了什麼,以及如何確保這樣的場景不會在生產中掛起?我是否對我的main()有一個巨大的catch-all catch子句並讓它捕獲所有的Exception以便處理每個異常?

EDIT FOR CLARITY:的問題是更多或更少 - Why does an unhandled exception that is not explicitly thrown in a method's signature, nor handled by a caller, not crash the JVM?

回答

1

要回答你的問題:爲什麼未明確拋出一個方法的簽名,也沒有處理由呼叫者未處理的異常,不會崩潰的JVM?

假設這段代碼運行在一個線程中,原因是,除非你在Thread類或Thread實例上設置了UnhandledExceptionHandler,否則'main'線程組是默認UnhandledExceptionHandler。默認情況下,線程組通過將堆棧跟蹤記錄到system.out來處理未處理的異常,線程'死亡'並且JVM不會崩潰。

你可能想要考慮實現一個UnhandledExceptionHandler,它使用你的電子郵件框架來通知你這些失敗。

正如其他海報所建議的那樣,代碼應該清理finally塊中的Channels和Session等資源。

1

使用finally塊以確保連接被關閉。

public void closeConnection() { 
    try { 
     if (true) 
     throw new NullPointerException("Test unexpected exception NPE"); 
    } finally { 
     LOG.info("Closing SFTP connection"); 
     getSftpChannel().exit(); 
     getSession().disconnect(); 
     LOG.debug("SFTP Connection closed"); 
    } 
} 
+0

也許我應該更清楚一點 - 示例中的NPE僅用於測試目的......代碼顯然不僅僅是有新的NPE被無緣無故拋出; -P - 所以它沒有任何意義把整個代碼放在try/finally塊 – SnakeDoc

+0

中,然後把調用closeConnection放到finally塊中。 – Slihp

+0

問題是如果在代碼庫中任何*任何*未處理的異常被拋出*任何地方*,我得到這個掛起的JVM。不只是在這個示例方法中,而不僅僅是NPE的例子。 – SnakeDoc

相關問題