【问题标题】:Determine if a java application is in debug mode in Eclipse确定 java 应用程序是否在 Eclipse 中处于调试模式
【发布时间】:2010-11-09 16:33:25
【问题描述】:

我想根据我是否正在调试来更改日志记录级别,但我找不到代码 sn-p 来检查应用程序是否在调试模式下运行。

我正在使用 eclipse 来调试应用程序,所以如果该解决方案仅在 Eclipse 中有效,那就没问题了。

【问题讨论】:

    标签: java eclipse debugging logging


    【解决方案1】:

    how-to-find-out-if-debug-mode-is-enabled找到答案

    boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
        getInputArguments().toString().indexOf("-agentlib:jdwp") > 0;
    

    这将检查是否使用了Java Debug Wire Protocol 代理。

    【讨论】:

    • 布尔 isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean()。 getInputArguments().toString().contains("-agentlib:jdwp");
    • @FrankMeulenaar 这是非常特定于供应商的。这很好,只要你知道。
    • 请注意,一些调试器仍然使用旧参数-Xrunjdwp,我已经制作了这段代码来查找两个JVM args。
    • 如果 JMX 被禁用会怎样?
    • boolean isDebug = ManagementFactory.getRuntimeMXBean().getInputArguments().stream().anyMatch(arg -> arg.startsWith("-agentlib:jdwp"))
    【解决方案2】:

    您可以修改调试配置。例如,仅在调试配置中添加一个特殊的 VM 参数。您可以使用System.getProperties() 来读取提供的参数。

    更好的是,修改配置(运行和调试)以加载不同的日志记录配置文件。如果您需要编写代码来确定日志记录级别,那就不好了。这应该只是配置问题。

    【讨论】:

      【解决方案3】:

      没有官方认可的方法可以从 JVM 内部可靠地确定任何给定的 JVM 是否处于调试模式,并且依赖工件只会在未来某个时间破坏您的代码。

      因此,您需要自己介绍一种方法。建议:

      • 系统属性。
      • 环境变量(shell 变量,如 $HOME 或 %HOME%)
      • 向 JVM 询问给定资源的物理位置 - http://www.exampledepot.com/egs/java.lang/ClassOrigin.html - 并根据它做出决定(路径是否包含“调试”一词?它是在 jar 中还是在解压缩的类文件中?等等)。
      • JNDI
      • 特定资源的存在或内容。

      【讨论】:

      • 而且有时候你以后不用管代码,只需要现在能调试,正常情况下就可以了。
      • @user1663987 您仍然需要了解这些内容,以便在任何给定情况下选择最合适的方法。请注意,启用调试(出于所有实际目的,对被调试的程序来说是不可见的)和更改日志配置之间存在巨大差异 - 大多数程序员不会期望这会相互影响。
      【解决方案4】:

      您是否尝试过在 eclipse 运行配置中添加 vm 参数?

      将此作为 VM 参数传递

      -Ddebug=true
      

      那么您可以通过Boolean.getBoolean("debug") 进行检查。

      【讨论】:

      • Boolean.getBoolean("debug") 是愚蠢的,因为它试图将字符串 "debug" 转换为 bool,这总是导致 false。
      • @Daniel 正如 JavaDocs 关于此方法所说的那样,这是一种误导:当且仅当由参数命名的系统属性存在并且等于字符串“true”时才返回 true。因此,只要设置了这个属性,这个解决方案就可以工作。
      【解决方案5】:

      如果您是从自己的程序中设置调试级别,可能是这样的一行:

      public static final boolean DEBUG_MODE = System.getProperty("java.vm.info", "").contains("sharing");
      

      会成功的。

      刚刚在eclipse3.5中测试过:

      package test;
      
      public class Test
      {
      
          /**
           * @param args
           */
          public static void main(String[] args)
          {
              System.out.println(System.getProperty("java.vm.info", ""));
          }
      
      }
      

      将显示:

      mixed mode, sharing
      

      如果在没有调试的情况下启动

      mixed mode
      

      如果使用调试启动器执行


      Joachim Sauercmets:

      这高度依赖于系统。
      我假设“共享”表示跨 VM 类共享处于活动状态。
      这是一项非常新的功能,仅在某些平台上可用。
      此外,启用或禁用它的原因可能有很多,因此我不会将其用于调试模式检测。

      (注意:我使用最新的 jdk1.6b14 对其进行了测试。我将其保留为 CW 答案。)

      【讨论】:

      • 我在想可能有一个属性,但是我对调试启动和运行启动(使用 Eclipse 3.3、Java 1.6.0_13、Ubuntu 9.04)的属性的完整转储的测试是相同的。 (我还尝试了您的属性,包括我跨过 System.out 行的调试运行,并且运行和调试启动都给出了“混合模式”。
      • 这高度依赖于系统。我假设“共享”表示跨 VM 类共享处于活动状态。这是一项非常新的功能,仅在某些平台上可用。此外,启用或禁用它的原因可能有很多,因此我不会将其用于调试模式检测。
      • @Joachim:好点(我在这里使用最新的 jdk 1.6b14)。我将更新我的答案并将其作为社区 Wiki 存档。
      • 依赖缩进供人类阅读的字符串属性的内容充其量是脆弱的。
      • @ThorbjørnRavnAndersen 我同意(并赞成您的回答)。这是我 5 年前发现的。为了我的辩护,当时(2010 年 7 月),另一个产品被“字符串属性”更改咬住了:bugs.java.com/bugdatabase/view_bug.do?bug_id=6969236bugs.eclipse.org/bugs/show_bug.cgi?id=319514,对于“java.vendor
      【解决方案6】:

      看看这里:

      http://wiki.eclipse.org/FAQ_How_do_I_use_the_platform_debug_tracing_facility%3F

      此外,我认为您无法知道您的应用是否在调试模式下运行。您唯一能做的就是在调试时将参数传递给 JVM。

      手动

      【讨论】:

      • 那个是用于eclipse平台/插件跟踪的,不是正常调试的。
      【解决方案7】:

      如果使用套接字(例如 9999),您可以调用 netstat 来检查是否建立了连接:

      Process p = new ProcessBuilder("netstat", "-n").start();
      String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
      

      然后在标准输出中扫描 127.0.0.1:9999.*ESTABLISHED

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多