繁体   English   中英

如何从自定义SecurityManager的checkExit()方法确定哪个类称为System.exit()?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM