Q:

Why would JavaNGramExample fail with "java.lang.ClassNotFoundException: scala.collection.GenTraversableOnce$class"?

I am trying out a simple NGram example in spark
https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/ml/JavaNGramExample.java
This is my pom dependency
<dependencies>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.11</artifactId>
        <version>2.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-mllib_2.10</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>

Below is sample code
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");

        System.setProperty("hadoop.home.dir", "D:\\del");

         SparkSession spark = SparkSession
                  .builder()
                  .appName("JavaNGramExample").config("spark.master", "local")
                  .getOrCreate();

         List<Row> data = Arrays.asList(RowFactory.create(0, Arrays.asList("car", "killed", "cat")),
                    RowFactory.create(1, Arrays.asList("train", "killed", "cat")),
                    RowFactory.create(2, Arrays.asList("john", "plays", "cricket")),
                    RowFactory.create(3, Arrays.asList("tom", "likes", "mangoes")));

        StructType schema = new StructType(new StructField[] {
                new StructField("id", DataTypes.IntegerType, false, Metadata.empty()),
                new StructField("words", DataTypes.createArrayType(DataTypes.StringType), false, Metadata.empty()) });

        Dataset<Row> wordDataFrame = spark.createDataFrame(data, schema);

        NGram ngramTransformer = new NGram().setN(2).setInputCol("words").setOutputCol("ngrams");

        Dataset<Row> ngramDataFrame = ngramTransformer.transform(wordDataFrame);
        System.out.println(" DISPLAY NGRAMS ");
        ngramDataFrame.select("ngrams").show(false);

    }
}

I am getting the below error when I run this code.
Exception in thread "main" java.lang.NoClassDefFoundError: scala/collection/GenTraversableOnce$class
    at org.apache.spark.sql.types.StructType.<init>(StructType.scala:98)
    at com.mypackage.spark.learnspark.App.main(App.java:61)
Caused by: java.lang.ClassNotFoundException: scala.collection.GenTraversableOnce$class
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 2 more

I checked the dependency of scala and it is scala-library-2.11.8
Is there any inconsistency between spark 2.2.0 and my scala jars ?

A:

tl;dr Change spark-mllib_2.10 to spark-mllib_2.11 so Scala 2.11.8 is used for Spark MLlib dependency (and optionally remove spark-core_2.11 dependency).

See your pom.xml:
<dependencies>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.11</artifactId>
        <version>2.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-mllib_2.10</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>

spark-core_2.11 from Spark 2.2.0 depends on Scala 2.11.8 and that's OK.
spark-mllib_2.10 from Spark 2.2.0 depends on two different and incompatible Scala versions 2.10.x and 2.11.8. That's the root cause of the issue.

Make sure to use:

The same postfix for artifactId of your Spark dependencies, i.e. spark-core_2.11 and spark-mllib_2.11 (note that I changed it to 2.11).
The same version in every Spark dependency.

