[英]System.exit(0) does not prevent finally being called when have a SecurityManager.checkExit throw an exception
[英]How can I determine what class called System.exit() from the checkExit() method of a custom SecurityManager?
我正在写一个SecurityManager
,它只应允许来自单个类的System.exit()
调用。 问题在于,该类也是包含运行应用程序的main()
方法的类,因此使用SecurityManager.inClass()
将不起作用-我们始终在该类中。 我需要知道该类是否是明确要退出的类。 这有可能吗?
您可以查看StackTrace。
StackTraceElemment[] stes = Thread.currentThread().getStackTrace();
// find the first non system package
int i = 0;
for(; i < stes.length-1;i++)
if (!stes.getClassName().startsWith("java.lang."))
break;
// is that package/class ok?
if (stes[i].getClassName().startsWith("my.ok.package."))
使用内部API可以更有效地做到这一点,但是即使在Java版本的HotSpot之间,它们也不是标准的。
注意:如果已包含调试信息,这将为您提供方法名称,可能还会提供文件名和行号。 它不会给你的是实际的课程。 使用多个类加载器,您可以拥有多个具有相同名称的类,并且无法知道它是哪个类。 您得到的只是包和类名,而不是类加载器。
放在一起:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String className = stacktraceElements[stackTraceElements.length-1].getClassName();
if (className.contains("MainClassName")){
}
或者,您可以遍历stackTraceElements以查看它们是否是您的主类(或确保“正确”的是)。
这是我发现所有这些的方法:
请参阅以下有关如何获取堆栈跟踪的问题: 在Java中获取当前的堆栈跟踪
一旦有了StackTraceElements数组,就可以获取最后一个,然后从该数组中获取类。 (最后一个StackTraceElement是最新的)
参见以下问题以从堆栈跟踪中获取一个类: 如何使用堆栈跟踪或反射找到方法的调用方?
实际上,通过它的外观,您可以更轻松地获取类名,可以轻松地使用它来执行String.equals()检查:
if(className.equals("MainClassName")){
}
事实证明,根据http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html ,类名中也包含包信息。 因此,请改用String.contains()。
您可能可以制定仅向您的特定主类授予exitVM
权限的安全策略
策略文件必须有这样一行
permission java.lang.RuntimePermission ${yourMainClass} exitVM
有关此Blog的更多信息,我发现http://www.informit.com/articles/article.aspx?p=1187967&seqNum=3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.