Apache spark - java.lang.NoClassDefFoundError

时间:2015-10-31 00:30:46

标签: java scala jar apache-spark

我有基于maven的混合scala / java应用程序,可以提交spar作业。我的应用程序jar“myapp.jar”在lib文件夹中有一些嵌套的jar。其中一个是“common.jar”。我在清单文件中定义了类路径属性,如Class-Path: lib/common.jar。在纱线客户端模式下提交应用程序时,Spark执行程序会抛出java.lang.NoClassDefFoundError:com/myapp/common/myclass错误。类(com / myapp / common / myclass.class)和jar(common.jar)就在那里并嵌套在我的主myapp.jar中。胖jar是使用spring-boot-maven插件创建的,它将其他jar嵌套在父jar的lib文件夹中。我不想创建阴影平罐,因为这会产生其他问题。无论如何,spark执行器jvm可以在这里加载嵌套的jar?

编辑 spark(jvm classloader)可以在myapp.jar本身找到所有平坦的类。即com / myapp / abc.class,com / myapp / xyz.class等。

EDIT2 spark执行器类加载器也可以从嵌套jar中找到一些类,但它会在同一个嵌套jar中抛出NoClassDefFoundError其他一些类! 这是错误:

Caused by: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3, host4.local): java.lang.NoClassDefFoundError: com/myapp/common/myclass
    at com.myapp.UserProfileRDD$.parse(UserProfileRDDInit.scala:111)
    at com.myapp.UserProfileRDDInit$$anonfun$generateUserProfileRDD$1.apply(UserProfileRDDInit.scala:87)
    at com.myapp.UserProfileRDDInit$$anonfun$generateUserProfileRDD$1.applyUserProfileRDDInit.scala:87)
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
    at org.apache.spark.storage.MemoryStore.unrollSafely(MemoryStore.scala:249)
    at org.apache.spark.CacheManager.putInBlockManager(CacheManager.scala:172)
    at org.apache.spark.CacheManager.getOrCompute(CacheManager.scala:79)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:242)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61)
    at org.apache.spark.scheduler.Task.run(Task.scala:64)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:203)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: 
com.myapp.common.myclass
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 14 more

我确实使用sparkConf.setJar(String[] {"myapp.jar"})提交了myapp.jar,并尝试在spark.yarn.executor.extraClassPath上设置

编辑3 作为一种解决方法,我提取myapp.jar并手动设置sparkConf.setJar(String[] {"myapp.jar","lib/common.jar"})并且错误消失但显然我必须为所有嵌套jar执行此操作,这是不可取的。

1 个答案:

答案 0 :(得分:-2)

您可以使用--jars选项,在启动Spark应用程序时以逗号分隔的jar列表。

这样的东西
spark-submit --jars lib/abc.jar,lib/xyz.jar --class <CLASSNAME> myapp.jar