Der folgende Code wird in einer scala-Shell in der snakeyaml-Version 1.17
korrekt ausgeführt %Vor%Wenn jedoch in Spark (in diesem Fall 2.0.0) ausgeführt wird, lautet der resultierende Fehler:
%Vor%Ich habe die Scala-Shell mit
gestartet %Vor%Ich habe die Funkenschale mit
gestartet %Vor% Erstellen Sie eine eigenständige Anwendung und führen Sie sie mit% aus co_de% anstelle von spark-submit
.
Ich habe ein minimales Projekt für dich als hier erstellt . Alles, was Sie tun müssen, ist, beide Dateien ( spark-shell
und build.sbt
) in ein Verzeichnis zu stellen und dann folgendes auszuführen:
um ein JAR zu erstellen. Die JAR wird in Main.scala
oder einem ähnlichen Ort sein. Sie können SBT von hier erhalten , wenn Sie es noch nicht benutzt haben. Schließlich können Sie das Projekt ausführen:
Die Ausgabe sollte lauten:
%Vor% Sparks Shell ( REPL ) transformiert alle Klassen, in denen Sie definieren es durch Hinzufügen von target/scala-2.11/sparksnakeyamltest_2.11-1.0.jar
-Parameter zu Ihren Konstruktoren. Ich habe es hier erklärt . SnakeYAML erwartet einen Zero-Parameter-Konstruktor für JavaBean-ähnliche Klassen, aber es gibt keinen, so dass es fehlschlägt.
Sie können das selbst ausprobieren:
%Vor% Wie Sie sehen, transformiert Spark den Konstruktor, indem er einen Parameter vom Typ $iw
hinzufügt.
$iw
Wenn Sie wirklich in der Shell arbeiten müssen, könnten Sie Ihre eigene Klasse definieren, die Constructor
implementiert und sicherstellen, dass org.yaml.snakeyaml.constructor.BaseConstructor
an Konstruktoren übergeben wird, aber das ist eine Menge Arbeit (ich habe tatsächlich meine eigene geschrieben $iw
in Scala aus Sicherheitsgründen vor einiger Zeit, so habe ich einige Erfahrungen damit.)
Sie könnten auch eine benutzerdefinierte Constructor
fest codieren, um eine bestimmte Klasse ( Constructor
in Ihrem Fall) ähnlich der EmailAccount
wird in der SnakeYAML-Dokumentation angezeigt . Dies ist viel einfacher, erfordert jedoch das Schreiben von Code für jede Klasse, die Sie unterstützen möchten.
Beispiel:
%Vor% Sie können dies als Datei speichern und mit DiceConstructor
in die REPL laden.
Der Bonusvorteil dieser Lösung besteht darin, dass sie Instanzen von unveränderlichen Fallklassen direkt erstellen kann. Leider scheint Scala REPL Probleme mit Importen zu haben, daher habe ich voll qualifizierte Namen verwendet.
Sie können YAML-Dokumente auch einfach als einfache Java-Maps analysieren:
%Vor%Auf diese Weise muss SnakeYAML keine Spiegelung verwenden.
Allerdings, da Sie Scala verwenden, empfehle ich es zu versuchen
MoultingYAML , welches ein Scala-Wrapper für SnakeYAML ist. Es analysiert YAML-Dokumente auf einfache Java-Typen und ordnet sie dann Scala-Typen zu (sogar Ihren eigenen Typen wie :load filename.scala
).
Tags und Links scala apache-spark snakeyaml