java类路径问题

wkftcu5l  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(362)

我正在尝试运行map/reduce作业,但遇到java.lang.nosuchmethoderror。我对此做了一些研究,当我的代码被执行(而不是编译)时就会出现这种情况。在编译期间,类和方法的正确版本存在,但在尝试运行时,正确的方法不可用。导致这种情况的jar文件是guava。我从印刷的书堆里知道的。尝试执行以下代码行时抛出错误:

ArrayDeque<Entry<String, String>> a = Queues.newArrayDeque();

这个jar是hadoop类路径的一部分,因为我使用的是cdhverson5.3.0。我已经尝试将正确版本的guava添加到类路径中,但是错误没有改变。我的问题如下:
我相信我已经正确地确定了这个问题。你觉得这合理吗?我以前从未遇到过这个错误。
我认为我需要从类路径中删除旧版本的guava并添加新版本。然而,我真的不知道从哪里开始纠正这一点。向hadoopjar发出的命令不包含旧版本的guava(在-libjar parm中)。当我发出命令“hadoop classpath”时,jar是hadoop类路径的一部分。所以我假设有一些hadoop配置文件我可以编辑使之消失。这是正确的方法,还是我还需要做些别的事情?
我使用的是Java7、CDH5.3.0和NetBeans8。
短暂性脑缺血发作

mkshixfv

mkshixfv1#

在我写这篇文章的时候,hadoop依赖于guava 11.0.2版。它在内部实现中大量使用库。
根据Guava的记载 Queues#newArrayDeque 方法已添加到版本12.0中。如果您的代码编译成功,那么这意味着编译类路径上的guava版本12.0或更高版本在构建时可用,但由于hadoop在运行时提供了版本11.0.2,因此该方法不存在,从而导致 NoSuchMethodError .
不幸的是,在hadoop中没有可靠的方法来替换不同的guava版本。具体来说,我建议您不要试图替换hadoop发行版中提供的guava11.0.2jar。用一个不同的guava版本替换它是未经测试的,这将有可能破坏集群的稳定性。
更广泛的问题是hadoop的依赖关系“泄漏”到它的客户机。hadoop-11656是一个未实现的特性请求,它将把hadoop的内部依赖关系与客户机隔离开来,这样您就可以更容易地在所需版本中使用像guava这样的公共库。同时,在实现该特性之前,我认为您唯一的选择是坚持使用Guava11.0.2API,或者尝试直接将您真正想要的一些guava代码内联到您自己的项目中。的代码 Queues#newArrayDeque 在github上可见。

public static <E> ArrayDeque<E> newArrayDeque() {
  return new ArrayDeque<E>();
}

在这种情况下,用直接调用 java.util.ArrayDeque 建造师。多亏了java7diamond操作符,它就不会太冗长了。

ArrayDeque<Entry<String, String>> a = new java.util.ArrayDeque<>();

相关问题