При разработке контейнеров, которые запускают код, написанный другими разработчиками, разумно защищать от вызовов System.exit. Если разработчик непреднамеренно вызывает System.exit и развертывает свой код для запуска вашим контейнером, это полностью останавливает процесс контейнера. Это можно контролировать с помощью вызова функции checkExit в SecurityManager.
По ссылке для SecurityManager checkExit:
Этот метод вызывается для текущего менеджера безопасности методомexit
класса Runtime
. Статус 0
указывает на успех; другие значения указывают на различные ошибки.
Таким образом, любой вызов exit вызывает этот метод, и нам просто нужно вызвать исключение, если мы не хотим, чтобы обработка продолжалась дальше. Мы определяем наш SecurityManager как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
public class StopExitSecurityManager extends SecurityManager { private SecurityManager _prevMgr = System.getSecurityManager(); public void checkPermission(Permission perm) { } public void checkExit( int status) { super .checkExit(status); throw new ExitTrappedException(); //This throws an exception if an exit is called. } public SecurityManager getPreviousMgr() { return _prevMgr; } } |
Теперь мы можем обеспечить простоту использования класса CodeControl, как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class CodeControl { public CodeControl() { super (); } public void disableSystemExit() { SecurityManager securityManager = new StopExitSecurityManager(); System.setSecurityManager(securityManager) ; } public void enableSystemExit() { SecurityManager mgr = System.getSecurityManager(); if ((mgr != null ) && (mgr instanceof StopExitSecurityManager)) { StopExitSecurityManager smgr = (StopExitSecurityManager)mgr; System.setSecurityManager(smgr.getPreviousMgr()); } else System.setSecurityManager( null ); } } |
CodeControl теперь можно использовать, как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
|
CodeControl control = new CodeControl(); try { control.disableSystemExit(); //invoke the methods and other classes that are not allowed to call System.exit. Object ret = invokeExecute(_method, runWith, parms); } finally { //finally enable exit control.enableSystemExit(); } |
Это предотвратит вызов методов внутри disable и разрешит вызовы для вызова System.exit, но позволит вашему коду вызывать его без проблем.