Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从自定义SecurityManager的checkExit()方法中确定调用System.exit()的类?_Java_Securitymanager - Fatal编程技术网

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