我正在尝试运行map / reduce作业,而我正在获取java.lang.NoSuchMethodError。我对此做了一些研究,这在我的代码执行(未编译)时出现。编译期间会出现类和方法的正确版本,但在尝试运行时,无法使用正确的方法。导致这种情况的jar文件是番石榴。我从打印的堆栈中知道这一点。我在尝试执行以下代码行时抛出错误:
ArrayDeque<Entry<String, String>> a = Queues.newArrayDeque();
这个jar是hadoop类路径的一部分,因为它附带了我正在使用的CDH第5.3.0节。我已经尝试将正确版本的guava添加到类路径中,但错误不会改变。我的问题如下:
我相信我已经正确地确定了这个问题。这对你来说是否合理?我之前从未遇到过这个错误。
我相信我需要从类路径中删除旧版本的guava并添加新版本。但是,我真的不知道从哪里开始纠正这个。发给hadoop jar的命令不包含旧版本的guava(在-libjar parm中)。当我发出命令“hadoop classpath”时,jar是hadoop类路径的一部分。所以我假设有一些我可以编辑的hadoop配置文件,以使其消失。这是正确的方法,还是还有其他一些我需要做的事情?
我正在使用Java 7,CDH 5.3.0,NetBeans 8.
TIA
答案 0 :(得分:0)
在我写这篇文章时,Hadoop依赖于Guava版本11.0.2。它在内部实现中使用了相当多的库。
根据Guava JavaDocs,版本12.0中添加了Queues#newArrayDeque
方法。如果您的代码编译成功,那么这意味着在构建时编译类路径上可以使用Guava 12.0或更高版本,但由于Hadoop在运行时提供了版本11.0.2,因此该方法不存在,从而导致{{ 3}}
不幸的是,在Hadoop中没有可靠的方法来换掉不同的Guava版本。具体来说,我建议您不要尝试更换Hadoop发行版中附带的Guava 11.0.2 jar。使用不同的Guava版本替换它是未经测试的,并且可能会破坏群集的稳定性。
更广泛的问题是Hadoop的依赖关系“泄露”给它的客户端。 NoSuchMethodError
是一个未实现的功能请求,它将Hadoop的内部依赖关系与客户端隔离开来,这样您就可以更轻松地在所需版本中使用像Guava这样的公共库。同时,在实现该功能之前,我认为您唯一的选择是坚持使用Guava 11.0.2 API,或者可能尝试将您真正想要的一些Guava代码直接内嵌到您自己的项目中。 HADOOP-11656的代码。
public static <E> ArrayDeque<E> newArrayDeque() {
return new ArrayDeque<E>();
}
在这种特殊情况下,通过直接调用java.util.ArrayDeque
构造函数来替换代码似乎很容易。感谢Java 7钻石操作员,它甚至不会更加冗长。
ArrayDeque<Entry<String, String>> a = new java.util.ArrayDeque<>();