Spark提交任务报NoSuchMethodError:refArrayOps错误排查与解决
问题现象
通过spark-submit向YARN集群提交Spark任务时触发运行时异常,使用的提交命令如下:
spark-submit --class lr --master yarn --deploy-mode client --driver-memory 4g --executor-memory --num-executors 4 --executor-cores 4 --queue xxxxx_p1 /dd/ff/ff/fff/dd/dd/ddd/ddd/Automation/full-1.0-SNAPSHOT.jar /dd/dd/dd/dd/dd/dd/dd/dd/dd/lr_srvc_dt.properties
错误栈信息
任务提交后抛出如下错误:
22/06/29 04:50:41 ERROR SparkSubmit$$anon$2: 'scala.collection.mutable.ArrayOps scala.Predef$.refArrayOps(java.lang.Object[])' java.lang.NoSuchMethodError: 'scala.collection.mutable.ArrayOps scala.Predef$.refArrayOps(java.lang.Object[])' at labresult$.main(labresult.scala:30) at labresult.main(labresult.scala) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52) at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:958) at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180) at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203) at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90) at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1060) at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1069) at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
当前环境配置
Scala version 2.12.15, OpenJDK 64-Bit Server VM, 11.0.14.1 Spark_Version:- version 3.2.0.3-eep-810 JDK-8
故障根因
该类报错由三类常见问题触发:
- 提交命令存在语法错误:
--executor-memory参数后未传入合法内存值,会干扰Spark启动时的参数解析逻辑。 - 核心根因为Scala版本二进制不兼容:
NoSuchMethodError: scala.Predef$.refArrayOps是Scala 2.12与2.13版本二进制不兼容的典型报错。Spark发行版会绑定固定Scala大版本编译,若业务代码打包时使用的Scala版本和集群Spark自带的Scala版本不一致,或者打包时将其他版本的Scala标准库打进了业务fat jar,运行时就会出现方法签名不匹配、找不到对应方法的问题。 - JDK版本混乱:当前环境同时存在JDK 8和JDK 11,使用的EEP厂商定制版Spark 3.2.0默认基于JDK 8编译构建,若提交任务或编译代码时使用JDK 11,会触发类加载、字节码兼容类异常。
可行解决方案
按以下顺序排查修复:
- 修正提交命令参数,为
--executor-memory补充合法内存值,修正后参考命令如下:
spark-submit --class lr --master yarn --deploy-mode client --driver-memory 4g --executor-memory 4g --num-executors 4 --executor-cores 4 --queue xxxxx_p1 /dd/ff/ff/fff/dd/dd/ddd/ddd/Automation/full-1.0-SNAPSHOT.jar /dd/dd/dd/dd/dd/dd/dd/dd/dd/lr_srvc_dt.properties
- 对齐Scala版本:在集群节点执行
spark-shell --version确认当前Spark绑定的Scala版本,保证业务代码构建时使用完全一致的Scala版本;打包时配置过滤规则,不要将Scala标准库打入业务jar包,运行时直接复用Spark集群自带的Scala依赖即可。 - 对齐JDK版本:全链路(代码编译环境、spark-submit提交节点)统一使用JDK 8,将
JAVA_HOME环境变量指向JDK 8安装路径,避免JDK版本差异导致的兼容问题。 - 若使用Maven构建项目,可参考如下配置修正打包规则:
<build> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>4.8.0</version> <configuration> <!-- 替换为和集群一致的Scala版本 --> <scalaVersion>2.12.15</scalaVersion> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <!-- 排除所有Scala相关类,不打入fat jar --> <exclude>scala/**</exclude> </excludes> </filter> </filters> </configuration> </plugin> </plugins> </build>
内容的提问来源于stack exchange,提问作者Palash Chaturvedi
相关产品推荐
相关产品推荐

