在开发运行其他开发人员编写的代码的容器时,请谨慎防范System.exit调用。 如果开发人员无意间调用了System.exit并将其代码部署为由您的容器运行,则它将完全降低容器进程。 可以使用SecurityManager中的checkExit函数调用来控制。
根据SecurityManager checkExit的参考 :
当前的安全管理器通过Runtime
类的exit
方法调用此方法。 状态0
表示成功;状态0
表示成功。 其他值表示各种错误。 因此,任何对exit的调用都将调用此方法,并且如果我们不希望继续进行处理,则只需抛出异常。 我们将SecurityManager定义如下:
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类,如下所示:
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());}elseSystem.setSecurityManager(null);}
}
现在可以按以下方式使用CodeControl:
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 exitcontrol.enableSystemExit();
}
这样可以防止在disable中调用方法,并允许调用System.exit,但允许您的代码毫无问题地调用它。
参考: 防止我们的JCG合作伙伴 Raji Sankar 致电System.exit,该邮件来自Reflections博客。
翻译自: https://www.javacodegeeks.com/2013/11/preventing-system-exit-calls.html