Java 如何从自定义SecurityManager的checkExit()方法中确定调用System.exit()的类?
我正在编写一个Java 如何从自定义SecurityManager的checkExit()方法中确定调用System.exit()的类?,java,securitymanager,Java,Securitymanager,我正在编写一个SecurityManager,它应该只允许从单个类调用System.exit()。问题是这个类也包含运行应用程序的main()方法,因此使用SecurityManager.inClass()将不起作用-我们总是在那个类中。我需要知道该类是否是显式尝试退出的类。这有可能吗?把所有这些放在一起: StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); String classNa
SecurityManager
,它应该只允许从单个类调用System.exit()。问题是这个类也包含运行应用程序的main()
方法,因此使用SecurityManager.inClass()
将不起作用-我们总是在那个类中。我需要知道该类是否是显式尝试退出的类。这有可能吗?把所有这些放在一起:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String className = stacktraceElements[stackTraceElements.length-1].getClassName();
if (className.contains("MainClassName")){
}
或者,您可以在stackTraceElements上循环,查看它们是否是您的主类(或者确保“正确”的一个是主类)
以下是我如何发现这一切的:
请参阅有关如何获取堆栈跟踪的问题:
一旦拥有StackTraceElements数组,就可以获取最后一个,然后从该数组中获取类。(最后一个StackTraceeElement是最近的一个)
请参见此问题以从堆栈跟踪获取类:
实际上,从外观上看,您可以更轻松地获得类名,您可以轻松地使用它来执行字符串检查。equals()检查:
事实证明,类名中也包含包信息。因此,请改用String.contains()。您可以查看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."))
stacktraceelement[]stes=Thread.currentThread().getStackTrace();
//查找第一个非系统包
int i=0;
对于(;i
有更有效的方法可以通过内部API实现这一点,但它们不是标准的,即使在HotSpot的Java版本之间也是如此
注意:如果包含调试信息,这将为您提供方法名,可能还有文件名和行号。它不会给你实际的课程。使用多个类加载器,您可以有多个同名的类,并且无法知道它是哪一个。您得到的只是包和类名,而不是类加载器。您可能可以制定一个安全策略,只向特定的主类授予exitVM
权限
策略文件必须有这样一行
permission java.lang.RuntimePermission ${yourMainClass} exitVM
我在这个博客上找到了更多信息我从哪里可以得到要测试的类?你应该编辑掉的实例。然后解释如何获取堆栈跟踪。他们可能得把它清理干净。他们会怎么做?我们知道相关元素总是在索引3,因为。。。?也许最好在堆栈跟踪中查找一个也有main
方法的类,然后在适当的情况下进行进一步检查。@TedHopp如果您是对的,可能并非所有JVM都是这样。
permission java.lang.RuntimePermission ${yourMainClass} exitVM