Статьи

Предотвращение вызовов System.exit

При разработке контейнеров, которые запускают код, написанный другими разработчиками, разумно защищать от вызовов 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, но позволит вашему коду вызывать его без проблем.

Ссылка: Предотвращение звонков System.exit от нашего партнера по JCG Раджи Санкара в блоге Reflections .