如何在 Scala 对象的 EMR 上使用 Spark 3 解决 "Failed to load class"

How to resolve "Failed to load class" with Spark 3 on EMR for Scala object

我正在尝试构建一个简单的基于 Scala 的 Spark 应用程序并在 EMR 中 运行 它,但是当我 运行 它时,我得到 Error: Failed to load class: com.myorganization.MyScalaObj。我的 Scala 文件是:

package com.myorganization

import org.apache.spark.sql.SparkSession

object MyScalaObj extends App {
  val spark = SparkSession.builder()
    .master(("local[*]"))
    .appName("myTestApp")
    .getOrCreate()

  val df = spark.read.csv("s3://my_bucket/foo.csv")
  df.write.parquet("s3://my_bucket/foo.parquet")
}

在现有 build.sbt 文件中,我添加了几行,包括 Scala 版本、Spark 库依赖项和 mainClass(我从 .[=20= 中找到的) ]

name := "sbtproj"

version := "0.1"

scalaVersion := "2.12.10"

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "3.0.0",
  "org.apache.spark" %% "spark-sql" % "3.0.0"
)

mainClass in (Compile, run) := Some("com.myorganization.MyScalaObj")

我构建了这个并得到了一个 MyScalaObj.class,我用 jar cf MyScalaObj.jar MyScalaObj.class 手动将其打包到一个 jar 中。我将其复制到我的 EMR 集群 运行ning Spark 3.0.0 和 Scala 2.12.10.

然后我尝试 运行 我的应用程序 spark-submit --class com.myorganization.MyScalaObj MyScalaObj.jar --deploy-mode cluster --master spark://x.x.x.x,但失败 Error: Failed to load class com.myorganization.MyScalaObj.

因为这整个过程对我来说很新,我不确定错误是否在我的 sbt 配置中(我根本不知道 sbt),Scala 对象本身是否缺少某些东西(例如,清单?),或者我如何调用 Spark。我在这里出错的可能原因是什么?

事实证明,我的问题出在构建 jar 文件的方式上。多年未做 Java,我忘记了合格的 class 名称——在本例中为 com.myorganization.MyScalaObj——需要反映在目录结构中。我是运行jar cf MyScalaObj.jar MyScalaObj.class,不过我应该已经上了两个目录了,运行jar cf MyScalaObj.jar com/.