001    /**
002    * Licensed to the Apache Software Foundation (ASF) under one
003    * or more contributor license agreements.  See the NOTICE file
004    * distributed with this work for additional information
005    * regarding copyright ownership.  The ASF licenses this file
006    * to you under the Apache License, Version 2.0 (the
007    * "License"); you may not use this file except in compliance
008    * with the License.  You may obtain a copy of the License at
009    *
010    *     http://www.apache.org/licenses/LICENSE-2.0
011    *
012    * Unless required by applicable law or agreed to in writing, software
013    * distributed under the License is distributed on an "AS IS" BASIS,
014    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015    * See the License for the specific language governing permissions and
016    * limitations under the License.
017    */
018    
019    package org.apache.hadoop.yarn;
020    
021    import java.lang.Thread.UncaughtExceptionHandler;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    import org.apache.hadoop.classification.InterfaceAudience.Public;
026    import org.apache.hadoop.classification.InterfaceStability.Evolving;
027    import org.apache.hadoop.util.ExitUtil;
028    import org.apache.hadoop.util.ShutdownHookManager;
029    
030    /**
031     * This class is intended to be installed by calling 
032     * {@link Thread#setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler)}
033     * In the main entry point.  It is intended to try and cleanly shut down
034     * programs using the Yarn Event framework.
035     * 
036     * Note: Right now it only will shut down the program if a Error is caught, but
037     * not any other exception.  Anything else is just logged.
038     */
039    @Public
040    @Evolving
041    public class YarnUncaughtExceptionHandler implements UncaughtExceptionHandler {
042      private static final Log LOG = LogFactory.getLog(YarnUncaughtExceptionHandler.class);
043      
044      @Override
045      public void uncaughtException(Thread t, Throwable e) {
046        if(ShutdownHookManager.get().isShutdownInProgress()) {
047          LOG.error("Thread " + t + " threw an Throwable, but we are shutting " +
048                    "down, so ignoring this", e);
049        } else if(e instanceof Error) {
050          try {
051            LOG.fatal("Thread " + t + " threw an Error.  Shutting down now...", e);
052          } catch (Throwable err) {
053            //We don't want to not exit because of an issue with logging
054          }
055          if(e instanceof OutOfMemoryError) {
056            //After catching an OOM java says it is undefined behavior, so don't
057            //even try to clean up or we can get stuck on shutdown.
058            try {
059              System.err.println("Halting due to Out Of Memory Error...");
060            } catch (Throwable err) {
061              //Again we done want to exit because of logging issues.
062            }
063            ExitUtil.halt(-1);
064          } else {
065            ExitUtil.terminate(-1);
066          }
067        } else {
068          LOG.error("Thread " + t + " threw an Exception.", e);
069        }
070      }
071    }