java - 上传到Hadoop集群时依赖版本不正确

标签 java maven hadoop mapreduce azure-hdinsight

我正在尝试使用 Azure HDInsight 在 Hadoop 群集上运行 MapReduce 作业。在我的 .jar 中,我有以下依赖项(来自 mvn dependency:tree):

[INFO] +- org.apache.avro:avro:jar:1.8.1:compile
[INFO] +- org.apache.avro:avro-mapred:jar:hadoop1:1.8.1:compile
[INFO] |  +- org.apache.avro:avro-ipc:jar:1.8.1:compile

当我编译 jar 并在我的机器上运行它时,一切正常。但是当我在 HDInsight 群集上运行它时,出现以下错误:

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.avro.Schema$Parser.parse(Ljava/lang/String;[Ljava/lang/String;)Lorg/apache/avro/Schema;
        at org.foo.bar.MyClass.<clinit>(MyClass.java:9)
        at org.foo.bar.Sample.main(Sample.java:242)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.\
java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:243)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:158)

这是一个依赖版本冲突 - org.apache.avro.Schema$Parser.parse 仅在 avro 版本 1.7.5 中定义(根据 this question ),因此它必须是集群中正在使用不同版本的软件包。但我的印象是依赖项打包在 jar 文件中,所以我很困惑为什么会发生这种情况。为什么会出现这种情况以及如何修复它(或者至少进一步检查问题,例如通过 ssh 进入集群并检查其中的文件)?

这里是我的 pom.xml 的依赖项部分:

<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro</artifactId>
  <version>1.8.1</version>
</dependency>

<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-mapred</artifactId>
  <version>1.8.1</version>
  <classifier>hadoop1</classifier>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-mapreduce-examples</artifactId>
  <version>2.7.3</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-mapreduce-client-common</artifactId>
  <version>2.7.3</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-core</artifactId>
  <version>1.1.0</version>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>2.7.3</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>

最佳答案

Maven JAR Plugin (默认绑定(bind)到 package 阶段)将包含依赖项:

create a jar file for your project classes

还有其他插件可以实现这样的目的:Maven Shade Plugin , Maven Assembly Plugin .

此外,这不是 dependency version conflict ,因为您没有对两个不同版本(在构建时)使用相同的依赖项,但您在运行时使用的是一个很可能是较旧版本(在服务器上)的版本,该版本尚未包含您引用的方法。

要在 JAR 声明中包含 org.apache.avro:avro-mapred,例如Shade 插件具有:

<artifactSet>
  <includes>
    <include>org.apache.avro:avro-mapred</include>
  </includes>
</artifactSet>

包含其所有类/资源或添加:

<filters>
  <filter>
    <artifact>org.apache.avro:avro-mapred</artifact>
    <includes>
      <include>org/apache/avro/Schema*</include>
    </includes>
  </filter>
</filters>

仅包含Schema 及其嵌套类。

关于java - 上传到Hadoop集群时依赖版本不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57257603/

相关文章:

java - 如何解决fabric-sdk-java中的 “instantiate chaincode”错误?

java - 在java中检查进程何时完成?

scala - 通过Spark Job Server运行作业

java - msbuild 中 java jar 的对应项是什么?

java - 启动 Logo 窗口 - Swing

maven - 从Maven的命令行参数中跳过exec-maven-plugin

java - 实例化 IdentityMapper 得到 ClassException。如何使用IdentityMapper?

java - 如何终止(或杀死)Java 中的 Hadoop 作业?

java - 管道和发布与快照构建

java - NIO 在单元测试中从 src/test/resources 加载文件