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

时间:2014-06-25 21:01:22

标签: java securitymanager

我正在编写SecurityManager,只允许来自单个班级的System.exit()次来电。问题是这个类也是包含运行应用程序的main()方法的类,所以使用SecurityManager.inClass()将不起作用 - 我们总是在那个类中。我需要知道该类是否是明确试图退出的类。这有可能吗?

3 个答案:

答案 0 :(得分:1)

你可以看一下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有更有效的方法,但它们不是标准的,即使在HotSpot的Java版本之间也是如此。

注意:如果包含调试信息,这将为您提供方法名称以及可能的文件名和行号。它不会给你的是实际的课程。使用多个类加载器,您可以拥有多个具有相同名称的类,并且无法知道它是哪一个。你得到的只是包和类名,而不是类加载器。

答案 1 :(得分:0)

全部放在一起:

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String className = stacktraceElements[stackTraceElements.length-1].getClassName();
if (className.contains("MainClassName")){
}

或者,您可以循环遍历stackTraceElements以查看它们中的任何一个是否是您的主类(或确保“正确”类)。

以下是我发现这一切的方法:

请参阅有关如何获取堆栈跟踪的问题:Get current stack trace in Java

获得StackTraceElements数组后,可以获取最后一个,然后从该数组中获取类。 (最后一个StackTraceElement是最新的)

请参阅此问题以从堆栈跟踪中获取类:How do I find the caller of a method using stacktrace or reflection?

实际上,通过它的外观,您可以更轻松地获取类名,您可以轻松地使用它来执行String.equals()检查:

if(className.equals("MainClassName")){
}

事实证明,根据http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html,类名也包含了包信息。所以请改用String.contains()。

答案 2 :(得分:0)

您可以制定一项安全政策,仅对您的特定主要类别授予exitVM权限

政策文件必须有这样的一行

permission java.lang.RuntimePermission ${yourMainClass} exitVM

有关此博客的更多信息,我发现http://www.informit.com/articles/article.aspx?p=1187967&seqNum=3