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 }