我试图运行一个地图/减少作业,我得到了一个java.lang.NoSuchMethodError。我对此做了一些研究,当我的代码被执行(而不是编译)时,就会出现这种情况。编译期间存在正确版本的类和方法,但在尝试运行时,正确的方法不可用。导致这种情况的jar文件是番石榴。我从打印的堆栈中知道这个。当试图执行以下代码行时,我抛出一个错误:
ArrayDeque<Entry<String, String>> a = Queues.newArrayDeque();这个jar是hadoop类路径的一部分,因为它附带了我正在使用的CDH第5.3.0节。我尝试在类路径中添加正确版本的番石榴,但是错误没有改变。我的问题如下:
我使用的是Java 7,CDH5.3.0,NetBeans 8。
提亚
发布于 2015-12-22 00:02:36
在我编写这篇文章时,Hadoop依赖于Guava版本11.0.2。它在内部实现中大量使用这个库。
根据番石榴JavaDocs,Queues#newArrayDeque方法是在12.0版本中添加的。如果您的代码编译成功,那么这意味着在编译类路径中可以在编译类路径上获得12.0或更高版本,但是由于11.0.2版本是由Hadoop在运行时提供的,所以该方法不存在,从而导致NoSuchMethodError。
不幸的是,在Hadoop中没有可靠的方法来替换不同的Guava版本。具体来说,我建议您不要尝试替换Hadoop发行版中提供的Guava 11.0.2 jar。用不同的番石榴版本取代它是未经测试的,它可能会破坏集群的稳定。
更广泛的问题是Hadoop的依赖关系“泄漏”到它的客户端。HADOOP-11656是一个未实现的特性请求,它将Hadoop的内部依赖项与客户端隔离开来,因此您可以更容易地在所需的版本中使用像Guava这样的公共库。同时,在实现该特性之前,我认为您唯一的选择是坚持使用Guava 11.0.2 API,或者可能尝试将您真正想要的某些番石榴代码直接插入到您自己的项目中。在GitHub上可见的代码。
public static <E> ArrayDeque<E> newArrayDeque() {
return new ArrayDeque<E>();
}在这种情况下,用直接调用java.util.ArrayDeque构造函数替换代码似乎很容易。幸亏有了Java 7菱形操作符,它才不会更加冗长。
ArrayDeque<Entry<String, String>> a = new java.util.ArrayDeque<>();https://stackoverflow.com/questions/34399457
复制相似问题