我不精通 java 安全管理器,因此想确认我的理解:
我有一个随机停止(关闭挂钩运行)的 java 进程,即使没有人杀死它的痕迹。结果,我决定安装一个安全管理器并覆盖checkExit(int status)
以确保停止的原因不是调用System.exit()
。基本上我是这样写的:
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int status) {
Thread.dumpStack();
super.checkExit(status);
}
});
我原以为我的程序会像往常一样运行,唯一的变化是如果调用 System.exit() 会转储堆栈跟踪。我发现事实并非如此。它无法以此安全异常开始:
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "config" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[na:1.8.0_74]
at java.security.AccessController.checkPermission(AccessController.java:884) ~[na:1.8.0_74]
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) ~[na:1.8.0_74]
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294) ~[na:1.8.0_74]
at java.lang.System.getProperty(System.java:717) ~[na:1.8.0_74]
at Main.main(Main.java:161) ~[na:na]
似乎 SecurityManager 没有复制默认行为,并且在阅读了它之后似乎它应用了默认策略,${JAVA_HOME}/jre/lib/security/java.policy
该策略非常严格。
当没有安全管理器时,Java 的真正默认行为是什么?是“允许一切”还是发生了其他事情?
如果我想复制默认行为,除了上面的单个调整之外,我应该安装什么作为安全管理器?
在最后一点上,我可以看到System.setSecurityManager()
实际上需要一个实例,java.lang.SecurityManager
这意味着我被迫使用该实现(依赖于策略文件)。覆盖该类中的方法以复制 NO 安全管理器的实际默认行为的最有效方法是什么?
编辑:根据下面的讨论,这似乎可以做到
System.setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
return; // no security manager behaviour
}
@Override
public void checkPermission(Permission perm, Object context) {
return; // no security manager behaviour
}
@Override
public void checkExit(int status) {
Thread.dumpStack();
super.checkExit(status);
}
});