Wie behebe ich den Fehler „java.lang.ClassNotFoundException“ in Spark auf Amazon EMR?
Ich möchte den Fehler „java.lang.ClassNotFoundException“ in Apache Spark auf Amazon EMR beheben.
Kurzbeschreibung
Der Fehler java.lang.ClassNotFoundException in Spark tritt aus den folgenden Gründen auf:
- Der spark-submit-Auftrag kann die relevanten Dateien im Klassenpfad nicht finden.
- Eine Bootstrap-Aktion oder eine benutzerdefinierte Konfiguration überschreibt die Klassenpfade. Dadurch nimmt das Klassen-Ladeprogramm nur die JAR-Dateien auf, die an dem Speicherort vorhanden sind, den du in deiner Konfiguration angegeben hast.
Lösung
Um den Fehler java.lang.ClassNotFoundException zu beheben, überprüfe die Stack-Ablaufverfolgung, um den Namen der fehlenden Klasse zu finden. Füge dann den Pfad des benutzerdefinierten JAR (das die fehlende Klasse enthält) zum Spark-Klassenpfad hinzu. Du kannst den Pfad des benutzerdefinierten JAR in einem aktuell ausgeführten Cluster, einem neuen Cluster oder beim Absenden eines Auftrags hinzufügen.
Den benutzerdefinierten JAR-Pfad zu einem laufenden Cluster hinzufügen
Füge in /etc/spark/conf/spark-defaults.conf den Pfad des benutzerdefinierten JAR an die Klassennamen an, die in der Fehler-Stack-Ablaufverfolgung angegeben sind.
Beispiel:
sudo vim /etc/spark/conf/spark-defaults.conf spark.driver.extraClassPath <other existing jar locations>:example-custom-jar-path spark.executor.extraClassPath <other existing jar locations>:example-custom-jar-path
Hinweis: Ersetze example-custom-jar-path durch deinen benutzerdefinierten JAR-Pfad.
Den benutzerdefinierten JAR-Pfad zu einem neuen Cluster hinzufügen
Wenn du einen neuen Cluster erstellst, gib ein Konfigurationsobjekt an, um den benutzerdefinierten JAR-Pfad zu vorhandenen Klassenpfaden in /etc/spark/conf/spark-defaults.conf hinzuzufügen. Verwende Amazon-EMR-Versionen 5.14.0 oder höher, um einen neuen Cluster zu erstellen.
Füge für Amazon EMR 5.14.0 bis Amazon EMR 5.17.0 Folgendes hinzu:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/*" } } ]
Gib für Amazon EMR 5.17.0 bis Amazon EMR 5.18.0 /usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar als zusätzlichen JAR-Pfad an:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*" } } ]
Aktualisiere für Amazon EMR 5.19.0 auf Amazon EMR 5.32.0 den JAR-Pfad wie folgt:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*" } } ]
Aktualisiere für Amazon EMR 5.33.0 auf Amazon EMR 5.36.0 den JAR-Pfad wie folgt:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/" } } ]
Für Amazon-EMR-Versionen 6.0.0 und höher kannst du die Konfiguration nicht verwenden, um den JAR-Pfad zu aktualisieren, da die conf-Datei mehrere JAR-Pfade enthält. Außerdem darf die Länge jeder Eigenschaftskonfiguration, die du aktualisierst, 1024 Zeichen nicht überschreiten. Füge eine Bootstrap-Aktion hinzu, um den benutzerdefinierten JAR-Speicherort an spark-defaults.conf weiterzugeben. Weitere Informationen findest du unter Wie aktualisiere ich alle Amazon-EMR-Knoten nach der Bootstrap-Phase?
Informationen zum Hinzufügen einer Bootstrap-Aktion findest du unter Hinzufügen benutzerdefinierter Bootstrap-Aktionen. Führe dann die folgenden Aktionen aus:
- Ersetze s3://example-bucket/Bootstraps/script_b.sh durch deinen Amazon Simple Storage Service (Amazon S3)-Pfad.
- Ersetze /home/hadoop/extrajars/* durch deinen benutzerdefinierten JAR-Dateipfad.
- Vergewissere dich, dass die Amazon-EMR-Laufzeitrolle über die erforderlichen Berechtigungen für den Zugriff auf den Amazon-S3-Bucket verfügt.
Hinweis: Wenn du das Bootstrap-Skript hinzufügst, gilt das Skript für die Spark-Konfiguration des Clusters und nicht für einen bestimmten Auftrag.
Beispiel-Skript zum Ändern von /etc/spark/conf/spark-defaults.conf:
#!/bin/bash # # This is an example of script_b.sh for changing /etc/spark/conf/spark-defaults.conf # while [ ! -f /etc/spark/conf/spark-defaults.conf ] do sleep 1 done # # Now the file is available, do your work here # sudo sed -i '/spark.*.extraClassPath/s/$/:\/home\/hadoop\/extrajars\/\*/' /etc/spark/conf/spark-defaults.conf exit 0 Launch the EMR cluster and add a bootstrap action similar to the following: #!/bin/bash pwd aws s3 cp s3://example-bucket/Bootstraps/script_b.sh . chmod +x script_b.sh nohup ./script_b.sh &
Hinweis: Ersetze example-bucket durch deinen Amazon-S3-Bucket.
Den benutzerdefinierten JAR-Pfad beim Absenden eines Auftrags hinzufügen
Um den benutzerdefinierten JAR-Pfad hinzuzufügen, wenn du einen Auftrag absendest, führe den Befehl spark-submit mit der Option jars aus. Weitere Informationen findest du unter Launching applications with spark-submit (Starten von Anwendungen mit spark-submit) auf der Apache-Spark-Website.
spark-submit --deploy-mode client --class org.apache.spark.examples.SparkPi --master yarn spark-examples.jar 100 --jars example-custom-jar-path
Hinweis: Ersetze example-custom-jar-path durch deinen benutzerdefinierten JAR-Pfad. Um Klassenkonflikte zu vermeiden, beziehe keine Standard-JARs ein, wenn du die Option jars verwendest. Beziehe beispielsweise spark-core.jar nicht ein, da es bereits im Cluster vorhanden ist. Weitere Informationen findest du unter Spark konfigurieren.
Ähnliche Informationen
Spark configuration (Spark-Konfiguration) auf der Apache Spark-Website
- Themen
- Analytics
- Tags
- Amazon EMR
- Sprache
- Deutsch

Relevanter Inhalt
AWS OFFICIALAktualisiert vor einem Jahr
AWS OFFICIALAktualisiert vor 3 Jahren
AWS OFFICIALAktualisiert vor einem Monat