java .lang.NoSuchMethodError: scala .Predef $ .refArrayOps в задании Spark с Scala - PullRequest
2 голосов
/ 08 мая 2020

Полная ошибка:

Исключение в потоке «main» java .lang.NoSuchMethodError: scala .Predef $ .refArrayOps ([Ljava / lang / Object;) [Ljava / lang / Объект; в org.spark_module.SparkModule $ .main (SparkModule. scala: 62) в org.spark_module.SparkModule.main (SparkModule. scala) в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в sun.reflect. NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl. java: 62) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl. java: 43) в java .lang.reflect.vo82 *. в орг. apache .spark.deploy.JavaMainApplication.start (SparkApplication. scala: 52) в орг. apache .spark.deploy.SparkSubmit.org $ apache $ spark $ deploy $ SparkSubmit $$ runMain (SparkSubmit . scala: 845) в организации apache .spark.deploy.SparkSubmit.doRunMain $ 1 (SparkSubmit. scala: 161) в организации apache .spark.deploy.SparkSubmit.submit (SparkSubmit. scala: 184) в организации apache .spark.deploy.SparkSubmit.doSubmit (SparkSubmit. scala: 86) в организации apache .spark.deploy.SparkSubmit $$ anon $ 2.doSubmit (SparkSubmit. scala: 920) в организации apache .spark.deploy.SparkSubmit $ .main (SparkSubmit. scala: 929) в организации apache .spark.deploy.SparkSub mit.main (SparkSubmit. scala)

Когда я компилирую и запускаю код в IntelliJ, он полностью выполняется нормально. Ошибка отображается, когда я отправляю .jar как искровое задание (время выполнения).

Строка 62 содержит: for ((elem, i) <- args.zipWithIndex). Я закомментировал остальную часть кода, чтобы быть уверенным, и ошибка продолжала отображаться в этой строке.

Сначала я подумал, что это ошибка zipWithIndex. Затем я изменил его на for (elem <- args) и угадайте, что, ошибка все еще показывалась. Вызывает ли это for?

Поиск в Google всегда указывает на несовместимость Scala версий между версией, используемой для компиляции, и версией, используемой во время выполнения, но я не могу найти решение.

Я пробовал this , чтобы проверить Scala версию, используемую IntelliJ, и вот все, что связано с Scala в Modules> Scala:

enter image description here

Затем я сделал это , чтобы проверить версию Scala во время выполнения, и результат:

(файл: / C: / Users / me / .gradle / caches / modules-2 / files-2.1 / org. scala -lang / scala -library / 2.12.11 / 1a0634714a956c1aae9abefc83acaf6d4eabfa7d / scala -library-2.12.11.jar)

Кажется, что версии совпадают ...

Это мой gradle.build (включает fatJar задачу )

group 'org.spark_module'
version '1.0-SNAPSHOT'

apply plugin: 'scala'
apply plugin: 'idea'
apply plugin: 'eclipse'

repositories {
    mavenCentral()
}

idea {
    project {
        jdkName = '1.8'
        languageLevel = '1.8'
    }
}

dependencies {
    implementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.11'
    implementation group: 'org.apache.spark', name: 'spark-core_2.12'//, version: '2.4.5'
    implementation group: 'org.apache.spark', name: 'spark-sql_2.12'//, version: '2.4.5'
    implementation group: 'com.datastax.spark', name: 'spark-cassandra-connector_2.12', version: '2.5.0'
    implementation group: 'org.apache.spark', name: 'spark-mllib_2.12', version: '2.4.5'
    implementation group: 'log4j', name: 'log4j', version: '1.2.17'
    implementation group: 'org.scalaj', name: 'scalaj-http_2.12', version: '2.4.2'
}

task fatJar(type: Jar) {
    zip64 true
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    } {
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }

    manifest {
        attributes 'Main-Class': 'org.spark_module.SparkModule'
    }

    with jar
}

configurations.all {
    resolutionStrategy {
        force 'com.google.guava:guava:12.0.1'
    }
}

compileScala.targetCompatibility = "1.8"
compileScala.sourceCompatibility = "1.8"

jar {
    zip64 true
    getArchiveFileName()
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    manifest {
        attributes 'Main-Class': 'org.spark_module.SparkModule'
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'

}

Чтобы создать (толстую) банку:

gradlew fatJar

в терминале IntelliJ.

Чтобы запустить задание:

spark-submit.cmd .\SparkModule-1.0-SNAPSHOT.jar

в Windows PowerShell.

Спасибо

РЕДАКТИРОВАТЬ:

spark-submit.cmd и spark-shell.cmd оба показывают Scala версию 2.11.12 , так что да, они отличаются от того, который я использую в IntelliJ ( 2.12.11 ). Проблема в том, что на странице загрузки Spark есть только один дистрибутив Spark для Scala 2.12 , и он поставляется без Hadoop; означает ли это, что мне нужно перейти с 2.12 до 2.11 в моем gradle.build ?

1 Ответ

3 голосов
/ 08 мая 2020

Я бы попробовал spark-submit --version узнать, что scala version использует spark

С spark-submit --version я получаю эту информацию

[cloudera@quickstart scala-programming-for-data-science]$ spark-submit --version
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.2.0.cloudera4
      /_/
                        
Using Scala version 2.11.8, Java HotSpot(TM) 64-Bit Server VM, 1.8.0_202
Branch HEAD
Compiled by user jenkins on 2018-09-27T02:42:51Z
Revision 0ef0912caaab3f2636b98371eb29adb42978c595
Url git://github.mtv.cloudera.com/CDH/spark.git
Type --help for more information.

из spark-shell попробуйте это, чтобы узнать scala version

scala> util.Properties.versionString
res3: String = version 2.11.8

OS может использовать другой scala version, в моем случае, как вы можете видеть, spark scala version и OS scala version разные

[cloudera@quickstart scala-programming-for-data-science]$ scala -version
Scala code runner version 2.12.8 -- Copyright 2002-2018, LAMP/EPFL and Lightbend, Inc.

Примечание От O'Really Learning Spark «Холден Карау, Энди Конвински, Патрик Венделл и Матей Захария»

Конфликты зависимостей

Одна иногда мешающая проблема связана с dependency conflicts в тех случаях, когда приложение пользователя и Spark зависят от одной и той же библиотеки. Это случается относительно редко, но когда это происходит, это может раздражать пользователей. Обычно это проявляется, когда NoSuchMethodError, ClassNotFoundException или какой-либо другой JVM exception, связанный с загрузкой класса, выдается во время выполнения задания Spark. Есть два решения этой проблемы. Первый - изменить ваше приложение, чтобы оно зависело от той же версии third-party library, что и Spark. Второй - изменить упаковку вашего приложения с помощью процедуры, которую часто называют « затенение ». Инструмент сборки Maven поддерживает затенение с помощью расширенной конфигурации надстройки, показанной в примере 7-5 (на самом деле, благодаря возможности затенение подключаемому модулю присвоено имя maven-shade-plugin). Затенение позволяет вам сделать вторую копию конфликтующего пакета под другим пространством имен и переписать код вашего приложения, чтобы использовать переименованную версию. Этот отчасти brute-force метод довольно эффективен при разрешении времени выполнения dependency conflicts. Для конкретных c инструкций о том, как затенять зависимости, см. Документацию к вашему инструменту сборки.

...