运行时间极短的应用调用System.exit导致Log4j日志无法打印

版权声明:转载请注明链接 https://blog.csdn.net/weixin_38569499/article/details/87945896

    最近在写代码的时候,写了一个奇怪的问题。我写了一个主函数,测试刚写一个方法,其中调用了Log4j的API去打印log,但是log打印不出来,检查配置文件也没有问题。代码如下:

public static void main(String[] args) {
    Logger logger = LogManager.getLogger(“MAIN”);
    String url = "http://******";
    String expectedPath = "******";
    try {
      String actualPath = mappingUrlToBackupPath(yuyiguoUrl);
      logger.info("actual path: " + actualPath);
      assert expectedPath.equals(actualPath);
      System.exit(0);
    } catch (Exception e) {
      logger.error(e);
      System.exit(-1);
    }
  }

    多番检查无果后,怀疑是System.exit导致的log4j打印日志的线程还没来得及把日志打印出来就被kill掉了。所以查看了一下System的源码和说明文档。

    如下是System类中的exit方法的源码和说明文档:

    /**
     * Terminates the currently running Java Virtual Machine. The
     * argument serves as a status code; by convention, a nonzero status
     * code indicates abnormal termination.
     * <p>
     * This method calls the <code>exit</code> method in class
     * <code>Runtime</code>. This method never returns normally.
     * <p>
     * The call <code>System.exit(n)</code> is effectively equivalent to
     * the call:
     * <blockquote><pre>
     * Runtime.getRuntime().exit(n)
     * </pre></blockquote>
     *
     * @param      status   exit status.
     * @throws  SecurityException
     *        if a security manager exists and its <code>checkExit</code>
     *        method doesn't allow exit with the specified status.
     * @see        java.lang.Runtime#exit(int)
     */
    public static void exit(int status) {
        Runtime.getRuntime().exit(status);
    }

    从源码可以看出,System.exit调用了Runtime的exit方法,关闭了整个运行环境。看说明文档也能发现,“Terminates the currently running Java Virtual Machine.”,直接关闭掉了整个虚拟机。可以判断,主线程在运行的过程中迅速执行到System.exit方法,此时log4j用于打印日志的线程还没有开始工作,但是System.exit被调用后,整个虚拟机都被关掉,log4j无法完成日志的打印。

    在这里也顺便提一下,exit方法传入的参数,只有值为0的时候才是正常退出,参数status是任意非0值都表示程序非正常退出。

猜你喜欢

转载自blog.csdn.net/weixin_38569499/article/details/87945896