2014-02-26 39 views
0

我們有一個通過Shell腳本實用程序觸發的Java作業。這是定期運行的。System.exit(STATUS_CODE)的任何替代方法或有關從Java返回錯誤代碼的最佳做法

現在,shell腳本需要一個退出代碼,以防作業失敗,從而觸發其他報警點。所以,我們的主類中有System.exit(STATUS_CODE),當發生任何異常時,在catch塊中調用它。主要方法如下所示。我們正在使用Spring。我們還在記錄器中配置了smtp,以便通過電子郵件發送所有ERROR級別日誌。現在,我們注意到System.exit在退出JVM時突然停止記錄器和其他線程。所以,我們在調用System.exit之前爲任何日誌記錄添加了一個Thread.sleep(10000)。

這是發送錯誤狀態碼到java腳本的最佳方式嗎?我們可以在不使用System.exit調用的情況下發送狀態嗎?任何需要System.exit時的最佳做法或建議(shudownhook ...)? Spring中的任何替代方法都會在DI容器退出時發送錯誤代碼?

private static Logger LOG = LoggerFactory.getLogger(Application.class); 
    public static void main(final String[] args) throws InterruptedException { 
      LOG.info("Starting Timeout Service..."); 
      try { 
       final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); 
       final SomeBean somebean = ctx.getBean(SomeBean.class); 
       somebean.doSomething(); 
      } catch (final Exception exception) { 
       LOG.error(exception.getMessage(), exception); 
       waitForLogToProcessAndExit(); 
      } 
      LOG.info("Timeout Service Completed"); 

    } 

    private static void waitForLogToProcessAndExit() throws InterruptedException { 
      Thread.sleep(10000); //Waiting for any logging to complete before firing System.exit 
      System.exit(1); 
    } 
+0

你可以使用finally塊我猜 –

+0

對不起。爲什麼不通過CommandLineJobRunner.class進行批處理?它已經使用退出代碼實現了命令執行程序。 –

回答

0

爲什麼你不只是單純的做的每一報告/錯誤處理調用System.exit過嗎? 據我所知,除了使用System.exit() AS記錄器probalby使用單獨的線程發送電子郵件,除了0之外,沒有其他方式強制JVM返回0以外的退出碼(因爲@fge指出我錯了,因爲異常會返回1) ,你必須等待它實際發送或實現電子郵件服務,它將從某種隊列中發送消息,並將其放在你的進程旁邊(認爲這是最好的選擇,因爲它可以用於將來每個組件都需要這樣的解決方案)。

+0

是的:從main()拋出的異常將使JVM以1 – fge

+0

作爲offtopic點退出,你是對的。 – Antoniossss

0

(邊注:代替Thread.sleep(10000)可以使用TimeUnit.SECONDS.sleep(10)

的「錯誤」這裏大概是記錄器使用守護線程;當JVM退出時,它將而不是等待這些線程完成。直接的結果是,如果線程無法在System.exit()之前發送郵件,則沒有郵件。

解決方法:

  • 一些谷歌上搜索的時候,我看到有log4j的至少,如果你有一個關於你appener,.close()它之前退出:這將確保隊列中的所有消息酡;或者你可以配置你的appender首先不要使用守護進程線程?
  • 只是使用普通的cron與適當的MAILTO,只是登錄到標準輸出:cron默認情況下將stdout和stderr的內容郵寄給給定的郵件地址。
相關問題