title: Log4J 2: Uncaught Exceptions: Not being logged to file
body: <p>I'm using Log4J 2 alongside TestNG and Java 7 with IntelliJ as the IDE for a web automation project.</p>
  
  <p>I'm trying to redirect the standard error output of all uncaught Exceptions to a Log4J 2 log file with level ERROR.</p>
  
  <p>I've created a subclass of an <code>UncaughtExceptionHandler</code> called <code>Log4J2UncaughtExceptionHandler</code> that is meant to log the uncaught exceptions to an output log file:</p>
  
  <pre><code>public class Log4JUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
      @Override
      public void uncaughtException(Thread t, Throwable e) {
          logger.error(e);
      }
  }
  </code></pre>
  
  <p>Then in the code, I have set the default <code>UncaughtExceptionHandler</code> to this newly created handler instance:</p>
  
  <pre><code>Thread.setDefaultUncaughtExceptionHandler(log4JUncaughtExceptionHandler);
  </code></pre>
  
  <p>...and then I have verified that the <code>UncaughtExceptionHandler</code> has been changed:</p>
  
  <pre><code>// Prints "2016-10-31 15:15:19,623 INFO  [Test worker] plugins.Log4JUtils (Log4JUtils.java:89) - test.java.utils.Log4JUncaughtExceptionHandler@118414c5"
  Log4JUtils.logInfo(Thread.getDefaultUncaughtExceptionHandler().toString());
  </code></pre>
  
  <p>...but then I raise an uncaught exception:</p>
  
  <pre><code>String s = null;
  s.charAt(0);
  </code></pre>
  
  <p>...and although the <code>NullPointerException</code> gets logged to the console for IntelliJ, it does not show up in the error file I've directed the error to.</p>
  
  <p>Moreover, when I place a debug point in the above <code>uncaughtException()</code> method, the debugger does NOT stop there.</p>
  
  <p>I am not sure why something like this is occurring. Are there some exceptions that are simply not tracked by <code>UncaughtExceptionHandlers</code>?</p>
  
  <h3>Stack trace</h3>
  
  <p>Here is the stack trace. I should note as well that the above consists of tests using Selenium and Firefox with a Gradle build. I've interjected the <code>NullPointerException</code> statements at the beginning of one of the test cases.</p>
  
  <pre><code>3:14:59 PM: Executing external task 'DEBUG_qa1TestFirefox'...
  :compileJava UP-TO-DATE
  :processResources UP-TO-DATE
  :classes UP-TO-DATE
  :compileTestJava UP-TO-DATE
  :processTestResources UP-TO-DATE
  :testClasses UP-TO-DATE
  Connected to the target VM, address: '127.0.0.1:56873', transport: 'socket'
  :DEBUG_qa1TestFirefox
  
  Default Suite STANDARD_OUT
      2016-10-31 15:15:08,044 INFO  [Test worker] plugins.Log4JUtils (Log4JUtils.java:89) - 
      -----------------------------------------------------------------------------
      ------------ The test is starting now at 2016-10-31-15-15-08-031 ------------
      -----------------------------------------------------------------------------
      15:15:08.044 [Test worker] INFO  test.java.utils.plugins.Log4JUtils - 
      -----------------------------------------------------------------------------
      ------------ The test is starting now at 2016-10-31-15-15-08-031 ------------
      -----------------------------------------------------------------------------
  
  Default Suite &gt; Firefox STANDARD_OUT
      2016-10-31 15:15:08,084 INFO  [Test worker] plugins.Log4JUtils (Log4JUtils.java:89) - 
      -------------------------------------------------
      ------------ Testing case #[6.0]: [] ------------
      -------------------------------------------------
      15:15:08.084 [Test worker] INFO  test.java.utils.plugins.Log4JUtils - 
      -------------------------------------------------
      ------------ Testing case #[6.0]: [] ------------
      -------------------------------------------------
      2016-10-31 15:15:16,862 INFO  [Test worker] plugins.Log4JUtils (Log4JUtils.java:89) - Browser opened in FIREFOX
      15:15:16.862 [Test worker] INFO  test.java.utils.plugins.Log4JUtils - Browser opened in FIREFOX
  
  Default Suite &gt; Firefox &gt; test.java.&lt;censored&gt; STANDARD_OUT
      2016-10-31 15:15:19,623 INFO  [Test worker] plugins.Log4JUtils (Log4JUtils.java:89) - test.java.utils.Log4JUncaughtExceptionHandler@118414c5
      15:15:19.623 [Test worker] INFO  test.java.utils.plugins.Log4JUtils - test.java.utils.Log4JUncaughtExceptionHandler@118414c5
  
  Default Suite &gt; Firefox &gt; test.java.&lt;censored&gt; FAILED
      java.lang.NullPointerException at &lt;censored&gt;.java:543
  Disconnected from the target VM, address: '127.0.0.1:56873', transport: 'socket'
  
  1 test completed, 1 failed
  There were failing tests. See the report at: file:///C:/Users/&lt;censored&gt;/build/reports/2016-10-31-03_15_04_628/Firefox/index.html
  
  BUILD SUCCESSFUL
  
  Total time: 29.899 secs
  3:15:29 PM: External task execution finished 'DEBUG_qa1TestFirefox'.
  </code></pre>
  
  <h3>TestNG method</h3>
  
  <p>The TestNG method where the <code>NullPointerException</code> is being called:</p>
  
  <pre><code>@Test(groups = {group1, group2})
  @TestMethodLabel(testNumber = 6, text = "")
  public final void testMethod1() {
  
      // DEBUG PURPOSES ONLY: Force a NullPointerException to be thrown.
      Log4JUtils.logInfo(Thread.getDefaultUncaughtExceptionHandler().toString());
  
      String s = null;
      s.charAt(0);
  
      // &lt;main test case code here&gt;
  }
  </code></pre>
  
  <h3>Full code for handler</h3>
  
  <pre><code>package &lt;censored&gt;;
  
  import &lt;censored&gt;;
  
  /**
   * A handler for uncaught exceptions.
   */
  public class Log4JUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
  
      /**
       * Run any code necessary to handle the uncaught exception (e).
       *
       * Any exception thrown by this method will be ignored by the
       * Java Virtual Machine.
       *
       * @param t the thread from which the Exception has been declared.
       * @param e the exception to raise.
       */
      @Override
      public void uncaughtException(Thread t, Throwable e) {
          Log4JUtils.OUTPUT_LOGGER.error(e.getStackTrace());
      }
  }
  </code></pre>
  
  <h3>Log4J2 configs (2 different files for stderr and stdout)</h3>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Configuration&gt;
      &lt;Appenders&gt;
          &lt;File name="STDOUT_FILE" fileName="${sys:logFilePath}" append="false"&gt;
              &lt;PatternLayout pattern="%d %t %-5p %c{2} - %m%n"/&gt;
              &lt;Filters&gt;
                  &lt;ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/&gt;
                  &lt;ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL"/&gt;
              &lt;/Filters&gt;
          &lt;/File&gt;
          &lt;File name="STDERR_FILE" fileName="${sys:errFilePath}" append="false"&gt;
              &lt;PatternLayout pattern="%d %t %-5p %c{2} - %m%n"/&gt;
          &lt;/File&gt;
          &lt;Console name="STDOUT" target="SYSTEM_OUT"&gt;
              &lt;Filters&gt;
                  &lt;ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/&gt;
                  &lt;ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL"/&gt;
              &lt;/Filters&gt;
              &lt;PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/&gt;
          &lt;/Console&gt;
          &lt;Console name="STDERR" target="SYSTEM_ERR"&gt;
              &lt;PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/&gt;
          &lt;/Console&gt;
      &lt;/Appenders&gt;
      &lt;Loggers&gt;
          &lt;Logger name="test.java.utils.plugins.Log4JUtils" level="TRACE"&gt;
              &lt;AppenderRef ref="STDERR" level="ERROR"/&gt;
              &lt;AppenderRef ref="STDOUT" level="INFO"/&gt;
              &lt;AppenderRef ref="STDOUT" level="WARN"/&gt;
              &lt;AppenderRef ref="STDERR" level="DEBUG"/&gt;
              &lt;AppenderRef ref="STDERR" level="FATAL"/&gt;
              &lt;AppenderRef ref="STDOUT" level="TRACE"/&gt;
              &lt;AppenderRef ref="STDERR_FILE" level="ERROR"/&gt;
              &lt;AppenderRef ref="STDOUT_FILE" level="INFO"/&gt;
              &lt;AppenderRef ref="STDOUT_FILE" level="WARN"/&gt;
              &lt;AppenderRef ref="STDERR_FILE" level="DEBUG"/&gt;
              &lt;AppenderRef ref="STDERR_FILE" level="FATAL"/&gt;
              &lt;AppenderRef ref="STDOUT_FILE" level="TRACE"/&gt;
          &lt;/Logger&gt;
      &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  
  <h3>The logger being called</h3>
  
  <p>The logger being called is in a class called <code>Log4JUtils</code>. Also, the actual logger being called is substituted in for the dummy name of the logger (see Log4JUncaughtExceptionHandler.java)</p>
  
  <pre><code>public class Log4JUtils {
  
      /**
       * The LOGGER for this class instance that writes output to log files.
       */
      private static final Logger OUTPUT_LOGGER = LogManager.getLogger(Log4JUtils.class.getName());
  
  }
  </code></pre>