如何从自定义 SecurityManager 的 checkExit() 方法中确定名为 System.exit() 的类?
Posted
技术标签:
【中文标题】如何从自定义 SecurityManager 的 checkExit() 方法中确定名为 System.exit() 的类?【英文标题】:How can I determine what class called System.exit() from the checkExit() method of a custom SecurityManager? 【发布时间】:2014-06-25 21:01:22 【问题描述】:我正在写一个SecurityManager
,它应该只允许来自单个类的System.exit()
调用。问题是这个类也是包含运行应用程序的main()
方法的类,所以使用SecurityManager.inClass()
将不起作用——我们总是在那个类中。我需要知道该类是否是明确尝试退出的类。这可能吗?
【问题讨论】:
【参考方案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 版本之间也是如此。
注意:如果已包含调试信息,这将为您提供方法名称以及可能的文件名和行号。它不会给你的是实际的课程。使用多个类加载器,您可以拥有多个具有相同名称的类,并且无法知道它是哪一个。你得到的只是包和类名,而不是类加载器。
【讨论】:
我们知道相关元素总是在索引 3,因为...?也许最好沿着堆栈跟踪查找一个也具有main
方法的类,然后在适当的情况下进行进一步检查。
@TedHopp 你说得对,可能并非所有 JVM 都如此。【参考方案2】:
把它们放在一起:
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()。
【讨论】:
我在哪里可以测试课程? 您应该编辑掉instanceof
。然后解释如何获取堆栈跟踪。他们可能不得不清理它。他们会怎么做?【参考方案3】:
您可能可以制定一个安全策略,只向您的特定主类授予 exitVM
权限
策略文件必须有这样一行
permission java.lang.RuntimePermission $yourMainClass exitVM
我在这个博客上找到了更多信息http://www.informit.com/articles/article.aspx?p=1187967&seqNum=3
【讨论】:
以上是关于如何从自定义 SecurityManager 的 checkExit() 方法中确定名为 System.exit() 的类?的主要内容,如果未能解决你的问题,请参考以下文章
如何从自定义列表视图中获取选定项目并在 toast 消息中打印?
如何从自定义 UIGestureRecognizer 触发 NavigationController 的 interactivePopGestureRecognizer