2016-07-19 10 views
2

Ich habe versucht, dieses Problem für eine Weile zu lösen, aber ich kann keine Antwort finden. Ich bin eine einfache Spark-Anwendung in Scala zu schreiben, die einen Nifi Empfänger instanziiert, und obwohl es erfolgreich mit SBT baut, erhalte ich die folgende Fehlermeldung, wenn ich versuche, die Anwendung auszuführen Funken einreichen:Abhängigkeitsfehler beim Ausführen einer Spark-Anwendung, die einen NiFi-Empfänger instanziiert

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 

Ich habe versucht, ein paar Variationen, aber das ist meine build.sbt Datei:

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" 

Es soll beachtet werden, dass, wenn ich die beide nifi Linien ändern mit zwei ersetzt den Scala-Äquivalente (dh die ersten Prozentzeichen in jeder Zeile zu verwenden, Prozentzeichen), ich erhalte tatsächlich den folgenden Fehler, wenn ich "sbt Paket" starte:

[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 

Wie bereits erwähnt, mit den einzelnen Prozentzeichen (und damit die Java-Abhängigkeiten verwenden) bekomme ich keinen Fehler beim Build, aber ich mache zur Laufzeit.

Der relevante Teil meiner Anwendung (mit bestimmten Namen entfernt) ist wie folgt:

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)) 

Der Fehler in die letzte Zeile bezieht sich hier, wo die NifiReceiver instanziiert wird - es ist nicht zu finden scheinen, dieser Klassenname irgendwo.

Ich habe weit eine Reihe von Ansätzen einschließlich der folgenden (separat) versucht: 1) Finden Sie die JAR-Dateien für Nifi-Funken-Empfänger und NIFI-Site-to-Site-Client und Hinzufügen von ihnen in einem Lib-Verzeichnis in meinem Projekt 2) Nach diesem Beitrag https://community.hortonworks.com/articles/12708/nifi-feeding-data-to-spark-streaming.html. Ich habe schließlich eine Kopie von spark-default.conf.template in meinem Spark-conf-Verzeichnis erstellt und sie in spark-defaults.conf umbenannt und die beiden Zeilen in Schritt 1 unter diesem Link in die Datei eingefügt (anstelle der tatsächlichen Namen und Orte) der fraglichen Dateien). Ich stellte dann sicher, dass ich alle notwendigen Importanweisungen hatte, die in den zwei Codebeispielen auf dieser Seite 3 verwendet wurden) Erstellen eines Projektverzeichnisses im Stammverzeichnis meines Anwendungsverzeichnisses und Erstellen einer Datei namens assembly.sbt darin. Ich habe dann die folgende Zeile in (wie hier verwiesen: https://github.com/sbt/sbt-assembly):

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

Danach lief ich dann „sbt Versammlung“ statt „sbt-Paket“ die Anwendung habe ein uber Glas zu schaffen, aber dies dann gescheitert als auch mit dem gleichen Fehler wie bei den „sbt-Paket“ mit den Scala Abhängigkeiten in der build.sbt Datei ausgeführt wird:

[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 

Bitte lassen Sie mich wissen, ob weitere Informationen erforderlich sind. Vielen Dank im Voraus für jede Hilfe.

Antwort

1

Okay, ich habe es geschafft, dieses Problem zu beheben, und hier ist die Antwort für alle, die interessiert sein könnten:

Die Antwort zurück in den uber-jar Weg zu gehen war und mit „sbt Versammlung“ statt von "sbt-Paket", um die notwendigen Abhängigkeitsgläser in mein Uber-Jar aufzunehmen.

1) Erstellen Sie ein Verzeichnis „Projekt“ unter dem Stamm genannt und legen Sie eine Datei mit dem Namen assembly.sbt dort folgende enthält (die Zugabe hier von meinem ursprünglichen Versuch, die Resolvern Linie):

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) Im Build.sbt Datei im Stammverzeichnis des Projekts Verwendung folgende Abhängigkeit Referenzen (dh nicht funken Version spezifisch):

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

ich auch markiert Funken Kern und Funken Streaming als „zur Verfügung gestellt“, dh

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

Das bedeutet, dass Sie den Funken separat bereitstellen müssen, aber das Uber-Glas wird nicht größer.

3) In der gleichen Datei, fügen Sie den folgenden Code mit Verschmelzungen zu behandeln, wenn die Abhängigkeiten in ziehen (das ist wichtig):

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

4) Stellen Sie sicher, dass die entsprechenden Import-Anweisungen in Ihrem scala vorhanden sind Datei, z

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

usw.

Dann, wenn Sie "sbt assembly" laufen sollte es erfolgreich bauen - einfach die jar verweisen, wenn "Funken Eintragen" nennen, dh

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

Es sollte beachtet werden dass der folgende Beitrag eine große Hilfe bei der Suche nach dieser Lösung war: java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils$ while running TwitterPopularTags

Verwandte Themen