Ошибка java.lang.ClassNotFoundException при запуске spark-submit

#scala #maven #apache-spark

#scala #maven #apache-spark

Вопрос:

Я хочу запустить spark-submit для моего приложения Scala Spark. Это шаги, которые я сделал:

1) выполните очистку Maven и пакет из IntellijIDEA, чтобы получить myTest.jar 2) выполните следующую команду spark-submit:

 spark-submit --name 28 --master local[2] --class org.test.consumer.TestRunner 
/usr/tests/test1/target/myTest.jar 
$arg1 $arg2 $arg3 $arg4 $arg5
 

Это TestRunner объект, который я хочу запустить:

 package org.test.consumer

import org.test.consumer.kafka.KafkaConsumer

object TestRunner {

  def main(args: Array[String]) {

    val Array(zkQuorum, group, topic1, topic2, kafkaNumThreads) = args

    val processor = new KafkaConsumer(zkQuorum, group, topic1, topic2)
    processor.run(kafkaNumThreads.toInt)

  }

}
 

Но spark-submit команда завершается ошибкой со следующим сообщением:

 java.lang.ClassNotFoundException: org.test.consumer.TestRunner
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.spark.util.Utils$.classForName(Utils.scala:225)
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$runMain(SparkSubmit.scala:686)
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:185)
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:210)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:124)
 

Я действительно не понимаю, почему объект TestRunner не может быть найден, если пакет указан правильно… Имеет ли это какое-то отношение к использованию object вместо class ?

Обновить:

Структура проекта (папка scala в настоящее время помечена как источники):

 /usr/tests/test1
  .idea
  src
    main
      docker
      resources
      scala
        org
          test
             consumer
                kafka
                    KafkaConsumer.scala
                TestRunner.scala
    test
  target
 

pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.test.abc</groupId>
    <artifactId>consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_2.11</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming-kafka_2.11</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-scala_2.11</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.sedis</groupId>
            <artifactId>sedis_2.11</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.lambdaworks</groupId>
            <artifactId>jacks_2.11</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.11</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-mllib-local_2.11</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.nscala-time</groupId>
            <artifactId>nscala-time_2.11</artifactId>
            <version>2.12.0</version>
        </dependency>
    </dependencies>

</project>
 

Комментарии:

1. Я почти уверен, что вы неправильно упаковали свой jar. Загляните в файл jar (в total commander или winrar …) и проверьте, есть ли в этом jar класс TestRunner. Если нет chceck, правильно ли вы используете плагин scala в maven.

2. проверьте свой jar с jar tf /usr/tests/test1/target/myTest.jar помощью add | grep TestRunner , если вы используете систему Linux.

3. Было бы здорово, если бы вы могли предоставить свою структуру каталогов.

4. @ViacheslavRodionov: Да, я на Linux. Я запустил эту команду. Должен ли быть какой-либо вывод в случае ошибки? Я не получил никаких выходных данных.

5. @VladoDemcak: Спасибо. Да, скорее всего, это так. Я пытаюсь назначить разные папки внутри проекта в качестве «источников», а затем выполнить mvn -Dscala-2.11 clean package . Все время одна и та же проблема. Как я могу узнать, находится ли class TestRunner в jar?

Ответ №1:

@FiofanS, проблема в вашей структуре каталогов.

Maven использует convention over configuratation политику. Это означает, что по умолчанию maven ожидает, что вы будете следовать набору правил, которые он определил. Например, он ожидает, что вы поместите весь свой код в src/main/java каталог (см. Стандартную структуру каталогов Maven). Но у вас нет вашего кода в src/main/java каталоге. Вместо этого у вас есть это в src/main/scala каталоге. По умолчанию maven не будет рассматриваться src/main/scala как исходное местоположение.

Хотя maven ожидает, что вы будете следовать правилам, которые он определил, но он не применяет их. Он также предоставляет вам способы настройки на основе ваших предпочтений.
В вашем случае вам нужно будет явно указать maven, чтобы src/main/scala он также рассматривался как одно из ваших исходных местоположений.

Для этого вам придется использовать плагин Maven Build Helper.
Добавьте приведенный ниже фрагмент кода в <project>...</project> тег в вашем pom.xml

   <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.7</version>
        <executions>
          <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>src/main/scala</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
 

Это должно решить вашу проблему.

Комментарии:

1. Я попробовал это решение. В частности, я определил источник как <sources> <source>src/main/scala</source> </sources> . Правильно ли это? Затем я выполнил очистку и пакет из Intellij, чтобы получить новый файл jar. После этого я запустил spark-submit и получил ту же проблему. Я также разархивировал файл jar, чтобы просмотреть содержимое. Я не видел ни одного класса scala внутри его папок. Только pom.xml и пом.свойства. Кстати, должен ли я манифестировать основной класс?

2. Да, вероятно, вам придется добавить основной класс в файл манифеста. Но проблема здесь не в этом, проблема в том, почему ваш класс TestRunner не упаковывается даже после использования плагина build helper. Вы уверены, что добавили именно тот код, о котором я упоминал выше? Кроме того, сделайте одну вещь, пока просто используйте команду mvn clean install и сообщите нам, был ли класс TestRunner упакован в jar или нет.

3. или просто используйте sbt 😉

4. Я, наконец, скопировал-вставил часть сборки из этого простого проекта scala-maven: github.com/jesperdj/scala-maven-example/blob/master/pom.xml , и это работает сейчас! это похоже на ваше решение с некоторыми дополнительными изменениями.

5. Спасибо. Можете ли вы открыть другой вопрос для этого. Возможно, нам придется предоставить вам некоторый код. Было бы неправильно публиковать этот код в качестве ответа здесь для этого сообщения.