我有以下
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 :(得分:2)
您可以在单独的进程中启动代码,并使用RMI与其进行通信。如果第三方代码调用System.exit
并终止其进程,则您的进程可以继续运行并在必要时重新创建子进程。
请注意,这种方法有一些注意事项:
答案 1 :(得分: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
而不是