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