首页 > 解决方案 > Spark 提交 ClassNotFoundException

问题描述

这个问题与 Apache Spark 本身一样古老,但仍然没有一个解决方案对我有帮助。我有以下类声明:

object Main {
  def main(args: Array[String]): Unit = {
  ...
}

类引用是 org.griat.rcse.Main (在 IntelliJ 中是 ctrl+shift+alt+c),同样保留在pom.xml

<groupId>org.griat.rcse</groupId>

我尝试运行它的方式:

spark-submit --master yarn --deploy-mode client --class org.griat.rcse.Main Glonass112-1.0-SNAPSHOT.jar

一旦它工作了,但在代码中发现了一个异常。在我修好它之后,我clean编辑package了它。虽然pom.xml没有改变(以及路径和类名),但它停止提交给 Spark,显示ClassNotFoundException

java.lang.ClassNotFoundException: org.griat.rcse.Main
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at org.apache.spark.util.Utils$.classForName(Utils.scala:238)
        at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:810)
        at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:167)
        at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:195)
        at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:86)
        at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:924)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:933)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

我还补充说maven-jar-plugin,并不是说它会有所帮助:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>org.griat.rcse.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

这种黑魔法的来源是什么,我该如何处理?

标签: scalaapache-spark

解决方案


看来您还没有创建一个“胖罐子”,一个具有所有所需依赖项的罐子。如果您不这样做,或者如果“提供”了某些依赖项,则这些依赖项将需要位于整个类路径中(检查以CLASSPATH.

如前所述,要创建一个胖 jar,您需要使用 Assembly 插件。请看问题:

Maven Jar Plugin 和 Maven Assembly Plugin 有什么区别?

这是添加了程序集插件的 pom 文件示例

相关线路:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
</plugin>

以下是组装插件的总体说明——请注意,您可能想要使用描述符 XML 文件,页面底部有说明。

您还可以轻松地确认您的 jar 是否包含该类:该类应在您运行时列出jar tf path/to/assembled.jar如文档所述。您可以使用grep使其更容易:jar tf path/to/assembled.jar|grep org.griat.rcse


推荐阅读