gpt4 book ai didi

hadoop MultipleInputs 因 ClassCastException 而失败

转载 作者:可可西里 更新时间:2023-11-01 14:09:07 26 4
gpt4 key购买 nike

我的hadoop版本是1.0.3,当我使用multipleinputs时,我得到了这个错误。

java.lang.ClassCastException: org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit cannot be cast to org.apache.hadoop.mapreduce.lib.input.FileSplit
at org.myorg.textimage$ImageMapper.setup(textimage.java:80)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:142)
at org.apache.hadoop.mapreduce.lib.input.DelegatingMapper.run(DelegatingMapper.java:55)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370)
at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:416)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)
at org.apache.hadoop.mapred.Child.main(Child.java:249)

我测试了单输入路径,没问题。只有当我使用

MultipleInputs.addInputPath(job, TextInputpath, TextInputFormat.class,
TextMapper.class);
MultipleInputs.addInputPath(job, ImageInputpath,
WholeFileInputFormat.class, ImageMapper.class);

我用谷歌搜索并找到了这个链接 https://issues.apache.org/jira/browse/MAPREDUCE-1178其中说 0.21 有这个错误。但是我用的是1.0.3,这个bug会不会又回来了。任何人都有同样的问题或者任何人都可以告诉我如何解决它?谢谢

这里是图像映射器的设置代码,第4行是错误发生的地方:

protected void setup(Context context) throws IOException,
InterruptedException {
InputSplit split = context.getInputSplit();
Path path = ((FileSplit) split).getPath();
try {
pa = new Text(path.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

最佳答案

根据我的评论,TaggedInputSplit 的 Javadoc 确认您可能错误地将输入拆分转换为 FileSplit:

/**
* An {@link InputSplit} that tags another InputSplit with extra data for use
* by {@link DelegatingInputFormat}s and {@link DelegatingMapper}s.
*/

我猜你的设置方法看起来像这样:

@Override
protected void setup(Context context) throws IOException,
InterruptedException {
FileSplit split = (FileSplit) context.getInputSplit();
}

不幸的是 TaggedInputSplit 不是公开可见的,因此您不能轻松地进行 instanceof 样式检查,然后进行强制转换,然后调用 TaggedInputSplit.getInputSplit () 获取实际的底层 FileSplit。因此,要么您需要自己更新源代码并重新编译和部署,发布一张 JIRA 票以要求在未来的版本中修复此问题(如果它尚未在 2+ 中采取行动)或执行一些讨厌的讨厌的 反射 hackery 以获取底层 InputSplit

这是完全未经测试的:

@Override
protected void setup(Context context) throws IOException,
InterruptedException {
InputSplit split = context.getInputSplit();
Class<? extends InputSplit> splitClass = split.getClass();

FileSplit fileSplit = null;
if (splitClass.equals(FileSplit.class)) {
fileSplit = (FileSplit) split;
} else if (splitClass.getName().equals(
"org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit")) {
// begin reflection hackery...

try {
Method getInputSplitMethod = splitClass
.getDeclaredMethod("getInputSplit");
getInputSplitMethod.setAccessible(true);
fileSplit = (FileSplit) getInputSplitMethod.invoke(split);
} catch (Exception e) {
// wrap and re-throw error
throw new IOException(e);
}

// end reflection hackery
}
}

反射 Hackery 解释:

随着 TaggedInputSplit 被声明为保护范围,它对 org.apache.hadoop.mapreduce.lib.input 包之外的类不可见,因此您不能在设置方法中引用该类。为了解决这个问题,我们执行了一些基于反射的操作:

  1. 检查类名,我们可以使用它的完全限定名来测试类型 TaggedInputSplit

    splitClass.getName().equals("org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit")

  2. 我们知道我们想要调用 TaggedInputSplit.getInputSplit() 方法来恢复包装的输入拆分,所以我们利用 Class.getMethod(..) 获取方法引用的反射方法:

    方法 getInputSplitMethod = splitClass.getDeclaredMethod("getInputSplit");

  3. 该类仍然不是公开可见的,所以我们使用 setAccessible(..) 方法覆盖它,阻止安全管理器抛出异常

    getInputSplitMethod.setAccessible(true);

  4. 最后,我们调用对输入拆分的引用的方法并将结果转换为 FileSplit(乐观地希望它是这种类型的实例!):

    fileSplit = (FileSplit) getInputSplitMethod.invoke(split);

关于hadoop MultipleInputs 因 ClassCastException 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11130145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com