【问题标题】:How can I determine what class called System.exit() from the checkExit() method of a custom SecurityManager?如何从自定义 SecurityManager 的 checkExit() 方法中确定名为 System.exit() 的类?
【发布时间】:2014-06-25 21:01:22
【问题描述】:

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

【问题讨论】:

    标签: java securitymanager


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-22
      • 2014-02-23
      • 2023-03-29
      • 2022-12-28
      • 2017-06-11
      • 2012-11-04
      • 1970-01-01
      • 2021-03-25
      相关资源
      最近更新 更多