scala - java.lang.NoSuchMethodError: Scala.Predef$.refArrayOps 在 Spark 作业中使用 Scala
问题描述
完整错误:
线程“main”中的异常 java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)[Ljava/lang/Object; 在 org.spark_module.SparkModule$.main(SparkModule.scala:62) 在 org.spark_module.SparkModule.main(SparkModule.scala) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke( NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.apache.spark.deploy.JavaMainApplication.start (SparkApplication.scala:52) 在 org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:845) 在 org.apache.spark.deploy.SparkSubmit。
当我在 IntelliJ 中编译和运行代码时,它一直运行良好。当我将 .jar 作为 spark 作业(运行时)提交时,会显示该错误。
第 62 行包含:for ((elem, i) <- args.zipWithIndex)
. 为了确定,我注释掉了其余的代码,并且错误一直显示在该行上。
一开始我以为是zipWithIndex
错。然后我改变了它for (elem <- args)
并猜猜是什么,错误仍然显示。是for
这个原因吗?
谷歌搜索总是指向用于编译的版本和运行时使用的版本之间的 Scala 版本不兼容,但我无法找到解决方案。
我试过这个来检查 IntelliJ 使用的 Scala 版本,这是Modules > Scala下与 Scala 相关的所有内容:
然后我这样做是为了检查 Scala 的运行时版本,输出是:
(文件:/C:/Users/me/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.12.11/1a0634714a956c1aae9abefc83acaf6d4eabfa7d/scala-library-2.12.11.jar)
版本似乎匹配...
这是我的gradle.build(包括fatJar
任务)
group 'org.spark_module'
version '1.0-SNAPSHOT'
apply plugin: 'scala'
apply plugin: 'idea'
apply plugin: 'eclipse'
repositories {
mavenCentral()
}
idea {
project {
jdkName = '1.8'
languageLevel = '1.8'
}
}
dependencies {
implementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.11'
implementation group: 'org.apache.spark', name: 'spark-core_2.12'//, version: '2.4.5'
implementation group: 'org.apache.spark', name: 'spark-sql_2.12'//, version: '2.4.5'
implementation group: 'com.datastax.spark', name: 'spark-cassandra-connector_2.12', version: '2.5.0'
implementation group: 'org.apache.spark', name: 'spark-mllib_2.12', version: '2.4.5'
implementation group: 'log4j', name: 'log4j', version: '1.2.17'
implementation group: 'org.scalaj', name: 'scalaj-http_2.12', version: '2.4.2'
}
task fatJar(type: Jar) {
zip64 true
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
manifest {
attributes 'Main-Class': 'org.spark_module.SparkModule'
}
with jar
}
configurations.all {
resolutionStrategy {
force 'com.google.guava:guava:12.0.1'
}
}
compileScala.targetCompatibility = "1.8"
compileScala.sourceCompatibility = "1.8"
jar {
zip64 true
getArchiveFileName()
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'org.spark_module.SparkModule'
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
要构建(胖)罐子:
gradlew fatJar
在 IntelliJ 的终端中。
要运行作业:
spark-submit.cmd .\SparkModule-1.0-SNAPSHOT.jar
在 Windows PowerShell 中。
谢谢
编辑:
spark-submit.cmd和spark-shell.cmd都显示 Scala 版本2.11.12,所以是的,它们不同于我在 IntelliJ 中使用的版本(2.12.11)。问题是,在Spark 的下载页面中,只有一个适用于 Scala 2.12 的 Spark 发行版,并且没有 Hadoop;这是否意味着我必须在我的gradle.build中从 2.12 降级到 2.11 ?
解决方案
我会尝试spark-submit --version
知道scala version
正在使用什么spark
随着spark-submit --version
我得到这个信息
[cloudera@quickstart scala-programming-for-data-science]$ spark-submit --version
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.2.0.cloudera4
/_/
Using Scala version 2.11.8, Java HotSpot(TM) 64-Bit Server VM, 1.8.0_202
Branch HEAD
Compiled by user jenkins on 2018-09-27T02:42:51Z
Revision 0ef0912caaab3f2636b98371eb29adb42978c595
Url git://github.mtv.cloudera.com/CDH/spark.git
Type --help for more information.
从spark-shell
你可以试试这个来了解scala version
scala> util.Properties.versionString
res3: String = version 2.11.8
OS
可能正在使用 other ,在我的scala version
情况下,你可以看到spark scala version
并且OS scala version
不同
[cloudera@quickstart scala-programming-for-data-science]$ scala -version
Scala code runner version 2.12.8 -- Copyright 2002-2018, LAMP/EPFL and Lightbend, Inc.
O'Really Learning Spark的 笔记“Holden Karau、Andy Konwinski、Patrick Wendell 和 Matei Zaharia”
依赖冲突
一个偶尔的破坏性问题是处理dependency conflicts
用户应用程序及其Spark
本身都依赖于同一个库的情况。这种情况相对较少出现,但如果出现,可能会让用户感到烦恼。通常,这将在作业执行期间抛出a NoSuchMethodError
、 aClassNotFoundException
或其他
与类加载相关的内容时表现出来。这个问题有两种解决方案。首先是修改您的应用程序以依赖于相同版本的应用程序。第二种是使用通常称为“<strong>shading”的过程修改应用程序的包装。构建工具通过例 7-5 所示插件的高级配置支持着色(其实就是着色JVM exception
Spark
third-party library
Spark
Maven
能力是插件命名的原因maven-shade-plugin
)。着色允许您在不同的命名空间下制作冲突包的第二个副本,并重写应用程序的代码以使用重命名的版本。这种brute-force
技术在解决运行时非常有效dependency conflicts
。有关如何遮蔽
依赖项的具体说明,请参阅构建工具的文档。
推荐阅读
- php - 什么是 parent:: 特征范围
- c++ - C++ 编译器错误:P1LinkedList.cpp:145:错误:重载 'to_string(int&)' 的调用不明确
- google-apps-script - 如何计算excel或工作表上一行中未突出显示的条目数
- android - 使用 android App 设置 Android TV 的输入
- python - 如何在 Selenium 和 Firefox 中检索原始 JSON 数据?
- css - CSS未在codeigniter 4中加载
- python - 有没有办法遍历列表和函数?
- postgresql - 如何使用 pgAdmin4 为数据库中的所有触发器和表生成脚本
- java - Google Drive API V3 下载返回 416 错误
- amazon-web-services - 负载均衡器初始请求容量