7

我正在使用hadoop-2.7.2并且我用 IntelliJ 做了一个 MapReduceJob。在我的工作中,我正在使用apache.commons.cli-1.3.1并将 lib 放入 jar 中。

当我在我的 Hadoop 集群上使用 MapReduceJob 时,我有一个NoSuchMethodError

线程“主”java.lang.NoSuchMethodError 中的异常:org.apache.commons.cli.Option.builder(Ljava/lang/String;)Lorg/apache/commons/cli/Option$Builder;

我不明白,因为该方法存在于类中Option,并且该类Option是从commons-cli.jar我的应用程序 jar 中提取的。此外,我的其他图书馆没有这个问题。

感谢您的时间。

4

3 回答 3

4

我们能够使用maven 类重定位来修复这个错误。如果您使用 shade 插件来构建您的 jar,请在 pom.xml 的相应部分下添加以下内容:

<!-- necessary to fix NoSuchMethodError: org.apache.commons.cli.Option.builder -->
                            <relocations>
                                <relocation>
                                    <pattern>org.apache.commons.cli</pattern>
                                    <shadedPattern>org.shaded.commons.cli</shadedPattern>
                                </relocation>
                            </relocations>

此外,还需要在依赖项部分的顶部添加对 commons-cli v1.3+ 的显式引用,然后再任何可能具有对旧版本 commons-cli 的传递引用的依赖项。

于 2017-05-03T21:37:36.183 回答
3

问题似乎与classloader加载类的方式有关。因为在static Builder classcommon-cli 1.4,而一些hadoop依赖项仍然指的是旧版本 - 问题发生了。

在我的情况下,通过将 jar 文件添加的顺序更改为负责在程序执行之前设置环境的 shell 脚本中的类路径来解决问题。早些时候,我将 jar 添加到类路径中,例如

CLASSPATH=<Hadoop Jars>:<Common CLI jar>:$CLASSPATH

改为

CLASSPATH=<Common CLI jar>:<Hadoop Jars>:$CLASSPATH

它解决了这个问题。

于 2017-07-06T19:20:20.517 回答
1

我们通过下一个 gradle 配置解决了这个问题:

 compile('org.apache.parquet:parquet-tools:1.9.0'){
  exclude module:"commons-cli"
 }
于 2016-12-05T20:59:57.440 回答