2016-07-19 2 views
2

Я пытался решить эту проблему некоторое время, но я не могу найти ответ. Я пишу простое приложение Спарка в Scala, который инстанцирует приемник Nifi, и хотя он успешно строит с SBT, я получаю следующее сообщение об ошибке при попытке запуска приложения с помощью искры подати:Ошибка зависимости при запуске приложения Spark, создающего приемник NiFi

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/nifi/spark/NiFiReceiver 
    at <app name>.main(main.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731) 
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) 
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206) 
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) 
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 
Caused by: java.lang.ClassNotFoundException: org.apache.nifi.spark.NiFiReceiver 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     ... 10 more 

Я попытался несколько вариантов, но это мой build.sbt файл:

name := "<application name here>" 
version := "1.0" 
scalaVersion := "2.10.5" 

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.2" % "provided" 
libraryDependencies += "org.apache.spark" %% "spark-streaming" % "1.6.2" % "provided" 
libraryDependencies += "org.apache.nifi" % "nifi-spark-receiver" % "0.7.0" 
libraryDependencies += "org.apache.nifi" % "nifi-site-to-site-client" % "0.7.0" 

следует отметить, что, если я меняю два Nifi линии использовать эквиваленты Scala (т.е. первый знак процента в каждой строке заменяется два процентных знаков), я действительно получаю следующую ошибку при запуске пакета «sbt»:

[error] (*:update) sbt.ResolveException: unresolved dependency: org.apache.nifi#nifi-spark-receiver_2.10;0.7.0: not found 
[error] unresolved dependency: org.apache.nifi#nifi-site-to-site-client_2.10;0.7.0: not found 

Как я уже упоминал ранее, с единственными знаками процента (и, следовательно, с использованием зависимостей Java), я не получаю ошибок при сборке, но во время выполнения.

Соответствующая часть моего приложения (с определенными именами удалены) выглядит следующим образом:

import org.apache.spark.SparkContext 
import org.apache.spark.SparkContext._ 
import org.apache.spark.SparkConf 
import java.time 
import java.time._ 
import org.apache.nifi._ 
import java.nio.charset._ 
import org.apache.nifi.spark._ 
import org.apache.nifi.remote.client._ 
import org.apache.spark._ 
import org.apache.nifi.events._ 
import org.apache.spark.streaming._ 
import org.apache.spark.streaming.StreamingContext._ 
import org.apache.nifi.remote._ 
import org.apache.nifi.remote.protocol._ 
import org.apache.spark.streaming.receiver._ 
import org.apache.spark.storage._ 
import java.io._ 
import org.apache.spark.serializer._ 

object <app name> { 
    def main(args: Array[String]) { 

     val nifiUrl = "<nifi url>" 
     val nifiReceiverConfig = new SiteToSiteClient.Builder() 
      .url(nifiUrl) 
      .portName("Data for Spark") 
      .buildConfig() 

     val conf = new SparkConf().setAppName("<app name>") 
     val ssc = new StreamingContext(conf, Seconds(10)) 
     val packetStream = ssc.receiverStream(new NiFiReceiver(nifiReceiverConfig, StorageLevel.MEMORY_ONLY)) 

Ошибка со ссылкой на последнюю строку здесь, где конкретизируется NifiReceiver - не может найти это имя класса в любом месте.

Я проделал много различных подходов, включая следующие (отдельно): 1) Поиск файлов jar для nifi-spark-receiver и nifi-site-to-site-client и их добавления в каталог lib в моем проекте 2) После этого сообщения https://community.hortonworks.com/articles/12708/nifi-feeding-data-to-spark-streaming.html. Я закончил создание копии spark-default.conf.template в моем каталоге Spark conf, переименовав его в spark-defaults.conf и добавив две строки на шаге 1 по этой ссылке в файл (заменяя фактические имена и местоположения данных файлов). Затем я убедился, что у меня есть все необходимые операторы импорта, которые использовались в двух примерах кода на этой странице. 3) Создал каталог проекта в корне каталога моего приложения, а затем создал в нем файл assembly.sbt. Затем я добавил следующую строку внутри (как указано здесь: https://github.com/sbt/sbt-assembly):

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") 

После этого я побежал «SBT сборку» вместо «SBT пакета», чтобы приложение создать убер банку, но это тогда не удалось а также с той же ошибкой, как при запуске «SBT пакета» с зависимостями Scala в файле build.sbt:

[error] (*:update) sbt.ResolveException: unresolved dependency: org.apache.nifi#nifi-spark-receiver_2.10;0.7.0: not found 
[error] unresolved dependency: org.apache.nifi#nifi-site-to-site-client_2.10;0.7.0: not found 

Пожалуйста, дайте мне знать, если требуются какая-либо дополнительная информация. Заранее благодарю за любую помощь.

ответ

1

Хорошо, так что мне удалось решить эту проблему, и вот ответ для тех, кто может быть заинтересован:

Ответ был идти вниз по маршруту убер-банку и использовать «сборки SBT» вместо из пакета «sbt», чтобы включить необходимые баны зависимости в моей uber-jar.

1) Создайте папку с именем «проект» под корень и поместите файл под названием assembly.sbt там, содержащий следующее (добавление здесь с моей первоначальной попытки, линии резольверы):

resolvers += Resolver.url("sbt-plugin-releases-scalasbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/")) 

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") 

2) В сборке.SBT файл в корневом каталоге проекта, ссылки на следующую зависимость, использование (т.е. не искра от версии):

libraryDependencies += "org.apache.nifi" % "nifi-spark-receiver" % "0.7.0" 
libraryDependencies += "org.apache.nifi" % "nifi-site-to-site-client" % "0.7.0" 

Я также отметили искровое ядро ​​и искровые потоки, «при условии», т.е.

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.2" % "provided" 
libraryDependencies += "org.apache.spark" %% "spark-streaming" % "1.6.2" % "provided" 

Это означает, что вам нужно обеспечить искру отдельно, но это перестает увеличивать размер uber-jar.

3) В том же файл, добавьте следующий код, чтобы иметь дело с слияниями при трогании зависимости в (это важно):

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => 
    { 
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard 
    case x => MergeStrategy.first 
    } 
} 

4) Убедитесь в том, что соответствующие операторы импорта присутствует в вашем Скале файл, например

import org.apache.nifi._ 
import org.apache.nifi.spark._ 

и т.д.

Затем при запуске «сборки SBT» он должен строить успешно - просто ссылаться на эту банку при вызове «искрового представить», т.е.

spark-submit --class "<application class name>" --master "<local or url>" "<path to uber-jar from project root directory>" 

Следует отметить, что следующая публикация оказала огромную помощь в поиске этого решения: java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils$ while running TwitterPopularTags