Amazon EMR の Spark で「java.lang.ClassNotFoundException」を解決するにはどうすればよいですか?

最終更新日: 2020 年 1 月 8 日

Amazon EMR の spark-submit または PySpark ジョブでカスタム JAR ファイルを使用すると、java.lang.ClassNotFoundException エラーが発生します。

簡単な説明

このエラーは、次のいずれかに該当する場合に発生します。

  • spark-submit ジョブが、クラスパスで関連ファイルを見つけることができない場合。
  • ブートストラップアクションまたはカスタム設定によってクラスパスが上書きされている場合。この場合、クラスローダーは、設定内で指定した場所に存在する JAR ファイルだけをピックアップします。

解決方法

不足しているクラスの名前を見つけるためにスタックトレースを確認します。次に、(不足しているクラスを含む) カスタム JAR のパスを Spark クラスパスに追加します。これは、クラスターの稼働中、新しいクラスターの起動時、またはジョブの投入時に実行できます。

実行中のクラスターでは:

/etc/spark/conf/spark-defaults.conf で、エラースタックトレースで指定されているクラス名にカスタム JAR のパスを追加します。次の例では、/home/hadoop/extrajars/* がカスタム JAR パスです。

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

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

新しいクラスターでは:

クラスターを作成するときに設定オブジェクトを指定して、/etc/spark/conf/spark-defaults.conf の既存のクラスパスにカスタム JAR パスを追加します。

注: このオプションを使用するには、Amazon EMR リリースバージョン 5.14.0 以降を使用してクラスターを作成する必要があります。

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

単一のジョブでは:

spark-submit を実行するときにカスタム JAR パスを渡すには、--jars オプションを使用してください。例:

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

注: クラスの競合を防ぐために、--jars オプションを使用するときは標準の JAR を含めないでください。たとえば、spark-core.jar はクラスター内にすでに存在するため、含めないでください。

分類の設定について詳しくは、「Spark の設定」を参照してください。