如何从自定义 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 消息中打印?

如何从自定义反应挂钩访问数据

如何判断 UITabBar 是不是从自定义视图打开?

如何从自定义函数中调用委托函数?

如何从自定义模块中正确导入函数

如何从自定义 UIGestureRecognizer 触发 NavigationController 的 interactivePopGestureRecognizer