java - 在 google dataproc 集群实例中的 spark-submit 上运行应用程序 jar 文件

标签 java jar apache-spark google-cloud-dataproc

我正在运行一个 .jar 文件,其中包含我需要打包的所有依赖项。其中一个依赖项是 com.google.common.util.concurrent.RateLimiter 并且已经检查过它的类文件在这个 .jar 文件中。

不幸的是,当我在我的 google 的 dataproc-cluster 实例的主节点上点击命令 spark-submit 时,我收到了这个错误:

Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
at com.google.common.util.concurrent.RateLimiter$SleepingStopwatch$1.<init>(RateLimiter.java:417)
at com.google.common.util.concurrent.RateLimiter$SleepingStopwatch.createFromSystemTimer(RateLimiter.java:416)
at com.google.common.util.concurrent.RateLimiter.create(RateLimiter.java:130)
at LabeledAddressDatasetBuilder.publishLabeledAddressesFromBlockstem(LabeledAddressDatasetBuilder.java:60)
at LabeledAddressDatasetBuilder.main(LabeledAddressDatasetBuilder.java:144)
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:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:672)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:120)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

似乎在覆盖我的依赖关系方面发生了一些事情。已经从这个 .jar 中反编译了 Stopwatch.class 文件并检查了该方法是否存在。那只是在我运行那个 google dataproc 实例时发生的。 我在执行 spark-submit 的进程上执行了 grep,我得到了标志 -cp,如下所示:

/usr/lib/jvm/java-8-openjdk-amd64/bin/java -cp /usr/lib/spark/conf/:/usr/lib/spark/lib/spark-assembly-1.5.0-hadoop2.7.1.jar:/usr/lib/spark/lib/datanucleus-api-jdo-3.2.6.jar:/usr/lib/spark/lib/datanucleus-rdbms-3.2.9.jar:/usr/lib/spark/lib/datanucleus-core-3.2.10.jar:/etc/hadoop/conf/:/etc/hadoop/conf/:/usr/lib/hadoop/lib/native/:/usr/lib/hadoop/lib/*:/usr/lib/hadoop/*:/usr/lib/hadoop-hdfs/lib/*:/usr/lib/hadoop-hdfs/*:/usr/lib/hadoop-mapreduce/lib/*:/usr/lib/hadoop-mapreduce/*:/usr/lib/hadoop-yarn/lib/*:/usr/lib/hadoop-yarn/*

我能做些什么来解决这个问题吗?

谢谢。

最佳答案

如您所见,Dataproc 在调用 Spark 时在类路径上包含 Hadoop 依赖项。这样做主要是为了让 Hadoop 输入格式、文件系统等的使用变得相当简单。缺点是您最终会使用 Hadoop 的 Guava 版本 11.02(请参阅 HADOOP-10101)。

如何解决这个问题取决于您的构建系统。如果使用 Maven,可以使用 maven-shade 插件将你的 guava 版本重新定位到一个新的包名下。这方面的一个例子可以在 GCS Hadoop Connector's packaging 中看到。 ,但它的症结在于 pom.xml 构建部分中的以下插件声明:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <relocations>
            <relocation>
              <pattern>com.google.common</pattern>
              <shadedPattern>your.repackaged.deps.com.google.common</shadedPattern>
            </relocation>
          </relocations>
        </execution>
      </execution>
    </plugin>

类似的重定位可以通过 sbt 的 sbt-assembly 插件、ant 的 jarjar 和 gradle 的 jarjar 或 shadow 来完成。

关于java - 在 google dataproc 集群实例中的 spark-submit 上运行应用程序 jar 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33922719/

相关文章:

java - 如何在Android中实现持久队列

java - 如何从 Excel VBA 运行 Java Eclipse?

java - 使用 String 或 Long 作为 Google App Engine 数据存储区 key

Java 安全异常无效的 SHA1 Jar 文件

java - 减少 jar 文件的大小?

python - PySPark - 确定操作后数据类型的函数

java - 将字节数组转换为串行通信中的实际字符串

java - 是否可以在Eclipse中自动将依赖的项目编译成jar?

azure - 如何在 Azure Databricks Notebook Run Now JSON 中提供集群名称

amazon-web-services - 无法使用适当的权限创建临时目录 :/mnt1/s3