2012-04-14 74 views
1

我有以下如何從不同的線程「捕獲」System.exit(-1)?

System.setSecurityManager(new SecurityManager() { 
    @Override 
    public void checkExit(int status) { 
     super.checkExit(status); 

     //custom exception extends SecurityException 
     throw new SystemExitCalledException(); 
    } 
}); 

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     //never reaches here somehow... 
     //maybe some3rdPartyStaticMethod sets this, too? 
    } 

}); 


try { 
    //this method spawns threads and some call System.exit(). 
    some3rdPartyStaticMethod.invoke(null, new Object[]{args}); 
} catch (SystemExitCalledException e) { 
    //it never reaches here because 
    //SystemExitCalledException is thrown on different thread?? 
    // 
} 

是否有辦法防止some3rdPartyStaticMethod的產生的線程的System.exit()的距離停止JVM電話嗎?

+0

也許您可以使用'SecurityManager'將'CallException.exit'的調用替換爲'SecurityException'。 – 2012-04-14 13:08:42

回答

2

您就可以開始在一個單獨的進程的代碼,並與它使用RMI通信。如果第三方代碼調用System.exit並殺死它的過程中,你的進程可以繼續運行,並在必要時重新創建子進程。

注意,有一些需要注意這種方法:

  • 這兩個進程不共享同一個堆空間。
  • 您需要元帥是在兩個進程之間傳遞的所有數據。這意味着數據必須是可序列化的。
  • 將有每一個方法調用一個相當大的開銷。如果您需要每秒撥打很多電話,這可能會帶來性能問題。
+2

+1限制您與不信任的代碼的交互是件好事。這樣它有自己的堆限制。等等 – 2012-04-14 13:16:36

+2

當然,但是Java確實有這個東西的SecurityManager,它避免了整個IPC的東西。不知道爲什麼這對他不起作用 - 也許政策文件在錯誤的位置? – Voo 2012-04-14 13:26:28

1

編寫自定義的SecurityManager政策應幫助 - 我從來沒有這樣做我自己:)

根據this post(向下滾動到下):

然而,當任何東西VM嘗試調用System.exit(),VM退出。由於這包括mvn的殘酷擊落,所以正常的mvn進程被中斷。 SecurityManager可用於防止代碼調用System.exit(),但沒有人提及副作用。

我的一位同事提到,你可以設置你的政策,全系統,啓動VM時,每個用戶和系統屬性和後快速測試這一事實證明,解決我的問題。自從我設法弄清楚瞭如何從我的代碼中設置我自己的策略(在設置SecurityManager之前),這就解決了我的問題。

我用下面的代碼:

//Setup security to prevent System.exit() 
SecurityManager sm = System.getSecurityManager(); 
URL policy = getClass().getClassLoader().getResource("jsdoc.policy"); 
System.setProperty("java.security.policy", policy.toString()); 
System.setSecurityManager(new JSDocSecurityManager(getLog())); 

通過一個簡單的,開闊的,策略文件閱讀本:

grant { 
    permission java.security.AllPermission; 
}; 

如果它的工作原理就應該捕捉在System.exit()請求,並拋出一個SecurityException,而不是

相關問題