title: Exception thrown from the UncaughtExceptionHandler
body: <p>I am writing an apk analysis program. I cannot go deep into details because it's research material. However, the point is that from time to time when I execute the analysis routine, I get the following message:</p>
  
  <pre><code>Exception: java.lang.NullPointerException thrown from the UncaughtExceptionHandler in thread "main"
  </code></pre>
  
  <p>This happens if I do not override the UncaughtExceptionHandler and also if I do, as you'll see from the code below. Since there is <strong>no stacktrace</strong> data I cannot know where that exception is coming from and what its cause really is.</p>
  
  <p>I hope you can help me...</p>
  
  <p>This is only the main code. There are three main operation that I have to execute. In order not to disclose particular information, I renamed them to A, B and C</p>
  
  <pre><code>public class MainScannerSequential {
  public static void main(String[] args) throws ParserConfigurationException, IOException, InterruptedException {
      final File target = new File(args[1]);
      final File result = new File(args[2]);
      final Options options = new Options(args);
  
      silentMode = options.contains("-s");
      noA = options.contains("-nl");
      noC = options.contains("-ne");
  
      aStrategy = Factory.createA();
      bScanner = Factory.createB();
      cDetector = Factory.createcC();
  
      examinedFiles = new PersistentFileList(Globals.EXAMINED_FILES_LIST_FILE);
  
      if (result.exists())
          resultsWriter = new BufferedWriter(new FileWriter(result, true));
      else {
          resultsWriter = new BufferedWriter(new FileWriter(result));
          resultsWriter.write("***");
          resultsWriter.newLine();
      }
  
      if (Globals.PERFORMANCE_FILE.exists())
          performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE, true));
      else {
          performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE));
          performancesWriter.write("***");
          performancesWriter.newLine();
      }
  
      Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
          @Override
          public void uncaughtException(Thread t, Throwable e) {
              if ((t != null) &amp;&amp; (t.getName() != null))
                  System.out.println("In thread : " + t.getName());
  
              if ((e != null) &amp;&amp; (e.getMessage() != null)) {
                  System.out.println(e.getClass().getName() + ": " + e.getMessage());
                  if (e.getStackTrace() != null)
                      for (StackTraceElement ste : e.getStackTrace())
                          if (ste != null)
                              System.out.println(ste.getFileName() + " at line " + ste.getLineNumber());
              }
          }
      });
  
      if (target.isDirectory()) {
          enumerateDirectory(target);
      } else {
          String name = target.getName().toLowerCase();
  
          if (name.endsWith(".apklist"))
              readFileList(target);
          else if (name.endsWith(".apk"))
              checkFile(target);
      }
  
      closeWriters();
  }
  
  private static void println(String message) {
      if (!silentMode)
          System.out.println(message);
  }
  
  private static void print(String message) {
      if (!silentMode)
          System.out.print(message);
  }
  
  
  private static void enumerateDirectory(File directory) {
      for (File file : directory.listFiles()) {
          checkFile(file);
  
          if (file.isDirectory())
              enumerateDirectory(file);
      }
  }
  
  private static void readFileList(File file) {
      try {
          BufferedReader reader = new BufferedReader(new FileReader(file));
          String line = null;
  
          while((line = reader.readLine()) != null) {
              File readFile = new File(line);
  
              if (readFile.exists())
                  checkFile(readFile);
          }
  
          reader.close();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  
  private static void checkFile(File file) {
      if (examinedFiles.contains(file)) {
          println("Skipped: " + file.getName());
          return;
      }
  
      if (!file.getName().toLowerCase().endsWith(".apk")) {
          return;
      }
  
      final Wrapper&lt;Double&gt; unpackingTime = new Wrapper&lt;Double&gt;(0.0);
      final ApplicationData data = unpack(file, unpackingTime);
  
      if (data == null) {
          return;
      }
  
      scanData(data, unpackingTime.value);
  }
  
  
  private static ApplicationData unpack(final File file, final Wrapper&lt;Double&gt; unpackingTime) {
      final Wrapper&lt;ApplicationData&gt; resultWrapper = new Wrapper&lt;ApplicationData&gt;(null);
      final Wrapper&lt;Exception&gt; exceptionWrapper = new Wrapper&lt;Exception&gt;(null);
  
      println("Unpacking: " + file.getName());
  
      unpackingTime.value = Stopwatch.time(new Runnable() {
          @Override
          public void run() {
              try {
                  resultWrapper.value = ApplicationData.open(file);
              } catch (Exception e) {
                  exceptionWrapper.value = e;
              }
          }
      });
  
      if (resultWrapper.value != null)
          println("Unpacked: " + file.getName());
      else if (exceptionWrapper.value != null)
          println("Dropped: " + file.getName() + " : " + exceptionWrapper.value.getMessage());
  
      return resultWrapper.value;
  }
  
  private static void scanData(final ApplicationData applicationData, Double unpackingTime) {
      String apkName = applicationData.getDecodedPackage().getOriginalApk().getAbsolutePath();
      println("Submitted: " + apkName);
  
      examinedFiles.add(applicationData.getDecodedPackage().getOriginalApk());
  
      final Wrapper&lt;Boolean&gt; aDetected = new Wrapper&lt;Boolean&gt;(false);
      final Wrapper&lt;Result&gt; bDetected = new Wrapper&lt;Result&gt;(new Result());
      final Wrapper&lt;Boolean&gt; cDetected = new Wrapper&lt;Boolean&gt;(false);
  
      final Wrapper&lt;Double&gt; aDetectionTime = new Wrapper&lt;Double&gt;((double)ANALYSIS_TIMEOUT);
      final Wrapper&lt;Double&gt; bDetectionTime = new Wrapper&lt;Double&gt;((double)ANALYSIS_TIMEOUT);
      final Wrapper&lt;Double&gt; cDetectionTime = new Wrapper&lt;Double&gt;((double)ANALYSIS_TIMEOUT);
  
      ExecutorService executor = Executors.newFixedThreadPool(3);
  
      executor.submit(new Runnable() {
          @Override
          public void run() {
              textDetectionTime.value = Stopwatch.time(new Runnable() {
                  @Override
                  public void run() {
                      bScanner.setUnpackedApkDirectory(applicationData.getDecodedPackage().getDecodedDirectory());
                      bDetected.value = bScanner.evaluate();
                  }
              });
          }
      });
  
      if (!noA)
          executor.submit(new Runnable() {
              @Override
              public void run() {
                  lockDetectionTime.value = Stopwatch.time(new Runnable() {
                      @Override
                      public void run() {
                          aStrategy.setTarget(applicationData.getDecodedPackage());
                          aDetected.value = aStrategy.detect();
                      }
                  });
              }
          });
  
      if (!noC)
          executor.submit(new Runnable() {
              @Override
              public void run() {
                  encryptionDetectionTime.value = Stopwatch.time(new Runnable() {
                      @Override
                      public void run() {
                          cDetector.setTarget(applicationData.getDecodedPackage());
                          cDetected.value = cDetector.detect();
                      }
                  });
              }
          });
  
      boolean timedOut = false;
      executor.shutdown();
  
      try {
          if (!executor.awaitTermination(ANALYSIS_TIMEOUT, TimeUnit.SECONDS)) {
              executor.shutdownNow();
              timedOut = true;
          }
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  
      try {
          resultsWriter.write(String.format("%s, %b, %b, %f, %b, \"%s\", %b\n",
                  apkName,
                  aDetected.value,
                  bDetected.value.isAccepted(),
                  bDetected.value.getScore(),
                  cDetected.value,
                  bDetected.value.getComment(),
                  timedOut));
  
          performancesWriter.write(String.format("%s, %f, %f, %f, %f, %d, %dl, %dl\n",
                  apkName,
                  aDetectionTime.value,
                  bDetectionTime.value,
                  cDetectionTime.value,
                  unpackingTime,
                  applicationData.getSmaliLoader().getClassesCount(),
                  applicationData.getSmaliLoader().getTotalClassesSize(),
                  applicationData.getDecodedPackage().getOriginalApk().length()));
  
          resultsWriter.flush();
          performancesWriter.flush();
      } catch (IOException e) { }
  
      // No longer deleting temp files
  
      if (!timedOut)
          println("Completed: " + apkName);
      else {
          print("Timeout");
  
          if (bDetectionTime.value == 0) print(" TextDetection");
          if (!noA &amp;&amp; (aDetectionTime.value == 0)) print(" LockDetection");
          if (!noC &amp;&amp; (cDetectionTime.value == 0)) print(" EncryptionDetection");
  
          println(": " + apkName);
      }
  }
  
  
  private static void closeWriters() throws IOException {
      resultsWriter.close();
      performancesWriter.close();
      examinedFiles.dispose();
  }
  
  
  private static final int ANALYSIS_TIMEOUT = 40; // seconds
  
  private static Boolean silentMode = false;
  private static Boolean noA = false;
  private static Boolean noC = false;
  
  private static PersistentFileList examinedFiles;
  private static BufferedWriter resultsWriter;
  private static BufferedWriter performancesWriter;
  
  private static A aStrategy;
  private static B bScanner;
  private static C cDetector;
  }
  </code></pre>
  
  <p>I labeled the question as multithread because the same happens in the multithreaded version, which I serialized using this code in order to debug that error. Notice that the NullPointerException is in thread main, not in other Executor-spawned threads.</p>