001    // Copyright 2010 Google Inc. All Rights Reserved.
002    
003    package com.google.common.util.concurrent;
004    
005    import static java.util.logging.Level.SEVERE;
006    
007    import com.google.common.annotations.Beta;
008    import com.google.common.annotations.VisibleForTesting;
009    
010    import java.lang.Thread.UncaughtExceptionHandler;
011    import java.util.logging.Logger;
012    
013    /**
014     * Factories for {@link UncaughtExceptionHandler} instances.
015     *
016     * @author gak@google.com (Gregory Kick)
017     * @since 8
018     */
019    @Beta
020    public final class UncaughtExceptionHandlers {
021      private UncaughtExceptionHandlers() {}
022    
023      /**
024       * Returns an exception handler that exits the system. This is particularly useful for the main
025       * thread, which may start up other, non-daemon threads, but fail to fully initialize the
026       * application successfully.
027       *
028       * <p>Example usage:
029       * <pre>public static void main(String[] args) {
030       *   Thread.currentThread().setUncaughtExceptionHandler(UncaughtExceptionHandlers.systemExit());
031       *   ...
032       * </pre>
033       */
034      public static UncaughtExceptionHandler systemExit() {
035        return new Exiter(Runtime.getRuntime());
036      }
037    
038      @VisibleForTesting static final class Exiter implements UncaughtExceptionHandler {
039        private static final Logger logger = Logger.getLogger(Exiter.class.getName());
040    
041        private final Runtime runtime;
042    
043        Exiter(Runtime runtime) {
044          this.runtime = runtime;
045        }
046    
047        @Override public void uncaughtException(Thread t, Throwable e) {
048          // cannot use FormattingLogger due to a dependency loop
049          logger.log(SEVERE, String.format("Caught an exception in %s.  Shutting down.", t), e);
050          runtime.exit(1);
051        }
052      }
053    }