/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hive.io; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.mapred.InputFormat; import org.apache.hadoop.mapred.JobConf; import org.apache.hadoop.mapred.RecordReader; import org.apache.hadoop.util.ReflectionUtils; /** * An exception handler chain that process the input exception by going through * all exceptions defined in this chain one by one until either one exception * handler returns true or it reaches the end of the chain. If it reaches the * end of the chain, and still no exception handler returns true, throw the * exception to the caller. */ public class HiveIOExceptionHandlerChain { public static final String HIVE_IO_EXCEPTION_HANDLE_CHAIN = "hive.io.exception.handlers"; @SuppressWarnings("unchecked") public static HiveIOExceptionHandlerChain getHiveIOExceptionHandlerChain( JobConf conf) { HiveIOExceptionHandlerChain chain = new HiveIOExceptionHandlerChain(); String exceptionHandlerStr = conf.get(HIVE_IO_EXCEPTION_HANDLE_CHAIN); List<HiveIOExceptionHandler> handlerChain = new ArrayList<HiveIOExceptionHandler>(); if (exceptionHandlerStr != null && !exceptionHandlerStr.trim().equals("")) { String[] handlerArr = exceptionHandlerStr.split(","); if (handlerArr != null && handlerArr.length > 0) { for (String handlerStr : handlerArr) { if (!handlerStr.trim().equals("")) { try { Class<? extends HiveIOExceptionHandler> handlerCls = (Class<? extends HiveIOExceptionHandler>) Class.forName(handlerStr); HiveIOExceptionHandler handler = ReflectionUtils.newInstance(handlerCls, null); handlerChain.add(handler); } catch (Exception e) { } } } } } chain.setHandlerChain(handlerChain); return chain; } private List<HiveIOExceptionHandler> handlerChain; /** * @return the exception handler chain defined */ protected List<HiveIOExceptionHandler> getHandlerChain() { return handlerChain; } /** * set the exception handler chain * @param handlerChain */ protected void setHandlerChain(List<HiveIOExceptionHandler> handlerChain) { this.handlerChain = handlerChain; } public RecordReader<?,?> handleRecordReaderCreationException(Exception e) throws IOException { RecordReader<?, ?> ret = null; if (handlerChain != null && handlerChain.size() > 0) { for (HiveIOExceptionHandler handler : handlerChain) { ret = handler.handleRecordReaderCreationException(e); if (ret != null) { return ret; } } } //re-throw the exception as an IOException throw new IOException(e); } /** * This is to handle exception when doing next operations. Here we use a * HiveIOExceptionNextHandleResult to store the results of each handler. If * the exception is handled by one handler, the handler should set * HiveIOExceptionNextHandleResult to be handled, and also set the handle * result. The handle result is used to return the reader's next to determine * if need to open a new file for read or not. */ public boolean handleRecordReaderNextException(Exception e) throws IOException { HiveIOExceptionNextHandleResult result = new HiveIOExceptionNextHandleResult(); if (handlerChain != null && handlerChain.size() > 0) { for (HiveIOExceptionHandler handler : handlerChain) { handler.handleRecorReaderNextException(e, result); if (result.getHandled()) { return result.getHandleResult(); } } } //re-throw the exception as an IOException throw new IOException(e); } }