运行Hadoop MapReduce作业出现java.lang.ArrayIndexOutOfBoundsException报错
异常原因
- 启动参数缺失:main方法中直接读取
args[0]、args[1]、args[2]三个参数,若提交MapReduce作业时传入的参数数量不足3个,会直接触发数组下标越界异常,这是最高概率的触发原因。 - 日期拆分逻辑无校验:尽管
split("-")[0]正常情况下不会触发越界,但如果输入数据中存在极端异常的首字段(比如空值、特殊符号乱码导致拆分逻辑异常),也存在小概率越界风险。 - 异常被吞噬:map方法中的catch块为空实现,即使代码运行出现异常也无法输出具体栈信息,提高了问题定位成本。
修复方案
1. 新增启动参数校验
在main方法最开头加入参数校验逻辑,提前拦截参数不足的异常场景:
public static void main(String[] args) throws Exception { // 新增参数校验逻辑 if (args.length < 3) { System.err.println("参数错误,请依次传入3个参数:输入文件路径、是否包含世界数据(true/false)、输出文件路径"); System.exit(1); } // 原有业务逻辑保持不变 long st = new Date().getTime(); Configuration conf = new Configuration(); conf.set("is_world",args[1]); // ... 剩余原有代码 }
2. 完善日期字段拆分校验
对日期字段的拆分逻辑加边界判断,避免异常数据导致的问题:
if(tok.hasMoreTokens()) { String dateRaw = tok.nextToken(); String[] dateSegs = dateRaw.split("-"); // 仅当拆分结果符合预期时才赋值年份,否则直接跳过当前行 if (dateSegs.length > 0) { date_year = dateSegs[0]; } else { return; } }
3. 补全异常捕获逻辑
不要空吞异常,添加异常日志输出方便问题定位:
catch(Exception e){ System.err.printf("处理行数据异常,行内容:%s,错误信息:%s%n", value.toString(), e.getMessage()); e.printStackTrace(); }
4. 新增配置项默认值
获取is_world配置时设置默认值,避免空指针异常:
public void setup(Context context) throws IOException, InterruptedException{ Configuration conf = context.getConfiguration(); // 第二个参数为默认值,避免配置为空导致的空指针 include_world = conf.get("is_world", "false"); }
内容的提问来源于stack exchange,提问作者Serigne Ahmadou Mbacke Fall
相关产品推荐
相关产品推荐

