Comment éliminer l'erreur « java.lang.ClassNotFoundException » dans Spark sur Amazon EMR ?

Date de la dernière mise à jour : 08/01/2020

Lorsque j'utilise des fichiers JAR personnalisés dans une tâche spark-submit ou PySpark sur Amazon EMR, je reçois le message d'erreur java.lang .ClassNotFoundException.

Brève description

Cette erreur se produit lorsque l'une des conditions suivantes est vérifiée :

  • La tâche spark-submit ne trouve pas les fichiers recherchés dans le chemin de classe.
  • Une action d'amorçage ou une configuration personnalisée annule les chemins de classe. Lorsque cela se produit, le chargeur de classe récupère uniquement les fichiers JAR existant à l'emplacement que vous avez défini dans votre configuration.

Solution

Vérifiez la trace de la pile pour trouver le nom de la classe manquante. Ensuite, ajoutez le chemin du JAR personnalisé (contenant la classe manquante) au chemin de classe Spark. Vous pouvez le faire lorsque le cluster est en cours d'exécution, lorsque vous lancez un nouveau cluster ou lorsque vous soumettez une tâche.

Sur un cluster en cours d'exécution :

Dans /etc/spark/conf/spark-defaults.conf, ajoutez le chemin du fichier JAR personnalisé aux noms de classe qui sont spécifiés dans l'erreur de trace de la pile. Dans l'exemple suivant, /home/hadoop/extrajars/* est le chemin du fichier JAR personnalisé.

sudo vim /etc/spark/conf/spark-defaults.conf

spark.driver.extraClassPath :/home/hadoop/extrajars/*
spark.executor.extraClassPath :/home/hadoop/extrajars/*

Sur un nouveau cluster :

Ajoutez le chemin du fichier JAR personnalisé aux chemins de classe existants dans /etc/spark/conf/spark-defaults.conf en fournissant un objet de configuration lorsque vous créez un cluster.

Remarque : pour utiliser cette option, vous devez créer un cluster à l'aide d'Amazon EMR, version 5.14.0 ou ultérieure.

[
  {
    "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/*"
    }
  }
]

Pour une seule tâche :

Utilisez l'option --jars pour passer le chemin du fichier JAR personnalisé lorsque vous exécutez spark-submit. Exemple :

spark-submit --deploy-mode client --class org.apache.spark.examples.SparkPi --master yarn spark-examples.jar 100 --jars /home/hadoop/extrajars/*

Remarque : pour éviter les conflits de classe, n'incluez pas les fichiers JAR standard lorsque vous utilisez l'option --jars. Par exemple, n'incluez pas le fichier spark-core.jar, car il existe déjà dans le cluster.

Pour plus d'informations sur les classifications de configuration, consultez Configurer Spark.