我正在运行一个 .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)
似乎发生了一些事情,覆盖了我的依赖关系。已经反编译了Stopwatch.class
来自此 .jar 的文件并检查该方法是否存在。当我在 google dataproc 实例上运行时,就发生了这种情况。
我做到了grep
在执行过程中spark-submit
我得到了旗帜-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 的包装,但其关键在于 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-assemble 插件、ant 的 jarjar 以及 gradle 的 jarjar 或 Shadow 来完成。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)