本文介绍MaxCompute Spark作业中常见的Java/Scala类冲突问题及解决方案。
类冲突问题概述
这类报错一般会抛出
java.lang.NoClassDefFoundError或方法找不到等异常,需要检查POM并排除冲突的依赖。问题原因:自定义JAR包中加入的部分依赖可能与Spark客户端
jars目录下的JAR包版本不一致,导致JVM在加载类时优先加载了用户的JAR包。
依赖方式provided和compile区别
provided:代码依赖该JAR包,但只在编译时需要,运行时会从集群中寻找相应的JAR包。很多时候将JAR包设置为provided类型,是因为这些JAR包已经在集群中提供了(主要是Spark客户端的jars目录)。如果不设置为provided,可能会发生类冲突、类/方法找不到等问题。compile:代码依赖该JAR包,在编译和运行时都需要。这类JAR包通常是与用户代码逻辑相关的三方库,集群中不存在,需要用户打到自己的JAR包中。
主JAR包必须是一个Fat JAR,必须将compile类型的依赖都打到用户JAR包中,这样在代码运行时才能加载到这些依赖类。
POM自检
需要设置为provided的JAR包
groupId为
org.apache.spark的JAR包:这类JAR包主要是社区版Spark的JAR包,已经在Spark客户端的
jars目录下提供,不需要打进用户的JAR包,在Spark客户端提交任务时自动上传到MaxCompute集群中。cupid-sdk:
该JAR包在任务提交时自动上传到MaxCompute集群中。
odps-sdk:
该JAR包在任务提交时自动上传到MaxCompute集群中。
hadoop-yarn-client:
该JAR包用于任务上传。该JAR包可能会被间接依赖,因此最好在打包之前检查并将该依赖排除。
不能设置为provided的JAR包
用户访问其他服务用到的JAR包。例如,访问MySQL等第三方服务需要用到的JAR包。