对于SerializedLambda,Spark失败并出现ClassNotFoundException

时间:2015-01-30 10:12:58

标签: java apache-spark

我正在学习火花,我的第一个程序是一个单词计数器,我在独立模式下执行程序时遇到了问题

当我在本地模式下执行代码时,我没有问题(setMaster("local"))但是当我尝试独立执行(使用主从)时,它没有完成(我已经运行了脚本) ./sbin/start-all.sh)。该程序运行。但是收集数据时会发生异常。 (在counter.collectAsMap()行)

错误如下:

15/01/30 15:23:54 WARN TaskSetManager: Lost task 1.0 in stage 0.0 (TID 1, ******): java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field org.apache.spark.api.java.JavaRDDLike$$anonfun$fn$1$1.f$3 of type org.apache.spark.api.java.function.FlatMapFunction in instance of org.apache.spark.api.java.JavaRDDLike$$anonfun$fn$1$1

,代码如下:

public class MainTest {
    public static void main( String[] args ) throws {
        String origin = "originPath";

        SparkConf conf = new SparkConf().setAppName("org.sparkexample.WordCount").setMaster("spark://localhost:7077");
        JavaSparkContext context = new JavaSparkContext(conf);
        JavaRDD<String> file = context.textFile(origin);
        JavaRDD<String> words = file.flatMap(s -> Arrays.asList(s.split(" ")));
        JavaPairRDD<String, Integer> pairs = words.mapToPair(word ->new Tuple2<>(word,1));
        JavaPairRDD<String, Integer> counter = pairs.reduceByKey(( valueA,valueB) ->valueA +valueB);
        Map<String,Integer> map = counter.collectAsMap();
        map.forEach((key,value)->System.out.println(key+"="+value));
    }
}

我的机器安装了Oracle Java 8,我使用./sbin/start-all.sh脚本启动主服务器和一个服务器

哪一个可能是错误?

更新:

我正在尝试Java 7实现,我还有其他问题:例外是:

15/01/30 12:47:21 WARN TaskSetManager: Lost task 1.0 in stage 0.0 (TID 1, ***): java.lang.ClassNotFoundException: com.c4om.l3p3.sparkTest.MainTest

也许这是配置问题?

Java7代码如下:

public static void countWordsJava7(String path,Boolean local, Boolean printResult){
    SparkConf conf = new SparkConf().setAppName("org.sparkexample.WordCount").setMaster("spark://localhost:7077");
    JavaSparkContext context = new JavaSparkContext(conf);
    JavaRDD<String> file = context.textFile(path);
    JavaRDD<String> words = file.flatMap(new FlatMapFunction<String, String>() {
        @Override
        public Iterable<String> call(String s) {
            return Arrays.asList(" ".split(s));
        }
    });
    JavaPairRDD<String, Integer> pairs = words.mapToPair(new PairFunction<String, String, Integer>() {
        @Override
        public Tuple2<String, Integer> call(String s) {
            return new Tuple2<String, Integer>(s, 1);
        }
    });
    JavaPairRDD<String, Integer> counter = pairs.reduceByKey(new Function2<Integer, Integer, Integer>() {
        @Override
        public Integer call(Integer i1, Integer i2) {
            return i1 + i2;
        }
    });
    Map<String, Integer> map = counter.collectAsMap();
}

3 个答案:

答案 0 :(得分:1)

ClassNotFoundException表示工人缺少班级。可能有不同的原因,取决于它抱怨的课程:

  • 它是您自己的软件包中的一个类。您尚未将带有代码的jar文件部署到worker。您可以使用SparkConf.setJars让Spark为您分配jar。

  • 它是一个系统类。这表明工作者使用的Java版本与应用程序不同。例如java.lang.invoke.SerializedLambda是一个Java 8类 - 如果它缺少,你的工作者正在运行Java 7。

  • 它是一个库类。您需要在所有工作者上安装库,或者使用SparkConf.setJars让Spark为您分配jar。

要调试此类问题,请在worker上打印类路径。

rdd.foreachPartition { p => println(System.getProperty("java.class.path")) }

答案 1 :(得分:0)

如果我像IDE一样从IDE运行代码,并且调用setJars(new String [] {&#34; /path/to/jar/with/your/class.jar&#,那么我有同样的错误cannot assign instance of java.lang.invoke.SerializedLambda 34;})在SparkConf实例上,然后它工作。

例如:

SparkConf conf = new SparkConf().setAppName("LineCount");
conf.setMaster("spark://localhost:7077")
conf.setJars(new String[] { "/home/path/MainTest.jar" });

答案 2 :(得分:0)

在SparkConf上设置jar路径然后它可以工作。 jar路径是maven或ant编译后的jar文件路径。

String master = "spark://localhost:7077";
    SparkConf conf = new SparkConf()
            .setAppName(WordCountTask.class.getName())
            .setMaster(master)
            .setJars(new String[]{"/home/user/Projects/spark-test/target/first-example-1.0-SNAPSHOT.jar"})

希望有所帮助。