使用spark-testing-base做单元测试时遇NoClassDefFoundError问题求助
解决Spark-Testing-Base单元测试里的NoClassDefFoundError问题
为啥会出这问题?
你碰到的java.lang.NoClassDefFoundError: org/apache/hadoop/mapred/MRVersion错误,核心原因是IDE和sbt的类路径规则不一样:
- IntelliJ默认会把标记为
provided的依赖也加到测试的类路径里,所以本地跑测试啥问题没有; - 但sbt默认在执行
test任务时,不会加载provided作用域的依赖——而你的Hadoop、Hive相关组件全设成provided了,这就导致测试时Hive的Shims组件初始化找不到需要的Hadoop MapReduce类。
生产环境把这些依赖设为provided是对的(集群会提供),但本地测试得自己把这些类拉进来才行。
怎么解决?
办法1:改sbt配置,让测试阶段能用provided依赖
在你的build.sbt里加这段配置,把provided的依赖也包含到测试的类路径中:
// 让测试阶段能访问到provided作用域的依赖 fullClasspath in Test ++= (fullClasspath in Runtime).value.filter { attr => attr.get(moduleID.key).exists(_.configurations.contains("provided")) }
办法2:单独给测试阶段加必要的依赖
要是不想动全局的provided配置,就单独在Test作用域下引入缺失的核心依赖:
libraryDependencies ++= Seq( // MRVersion类所在的依赖包 "org.apache.hadoop" % "hadoop-mapreduce-client-core" % "2.6.0-cdh5.8.4" % Test, // Hive Shims相关的依赖 "org.apache.hive" % "hive-shims" % "1.1.0-cdh5.8.4" % Test, "org.apache.hive.shims" % "hive-shims-common" % "1.1.0-cdh5.8.4" % Test )
额外提醒一下
你的spark-testing-base版本1.6.0_0.8.0和Spark 1.6.x是完全匹配的,这块没问题,不用调整。
验证一下
执行sbt clean test,应该就能搞定这个类找不到的错误了。
内容的提问来源于stack exchange,提问作者GGHOSH
相关产品推荐
相关产品推荐

