#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. Спасибо. Можете ли вы открыть другой вопрос для этого. Возможно, нам придется предоставить вам некоторый код. Было бы неправильно публиковать этот код в качестве ответа здесь для этого сообщения.