Spark Scala程序报错Could not find or load main class求助
咱们先拆解你遇到的问题:找不到主类的报错大概率是项目配置错误或者代码本身的结构问题,另外你的代码里还有几个编译/运行错误需要先修正,我一步步给你说:
一、主类相关的核心问题
1. 包声明缺失
你代码开头的//package com.jsonReader是注释,实际没有生效的包声明!如果你的类没有包,主类的全限定名就是json;如果想放在com.jsonReader包下,要把注释去掉,写成:
package com.jsonReader
这会直接影响构建工具找到主类的路径。
2. Maven/SBT配置里的主类指定错误
不管用Maven还是SBT,都必须明确指定主类的全限定名:
Maven配置(pom.xml)
确保Scala编译插件和打包插件里都配置了正确的主类:
<build> <plugins> <!-- Scala编译插件 --> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>4.6.1</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <!-- 没有包的话写json,有包的话写com.jsonReader.json --> <mainClass>json</mainClass> </configuration> </plugin> <!-- 打包成带依赖的jar,方便spark-submit运行 --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>json</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
同时要确保依赖版本和Scala版本匹配(比如Scala 2.12对应Spark 3.x、Play JSON 2.8.x)。
SBT配置(build.sbt)
name := "JsonFlattener" version := "1.0" scalaVersion := "2.12.15" // 依赖配置 libraryDependencies ++= Seq( "org.apache.spark" %% "spark-sql" % "3.2.4" % Provided, "com.typesafe.play" %% "play-json" % "2.8.2" ) // 指定主类,没有包写"json",有包写"com.jsonReader.json" mainClass in Compile := Some("json")
二、代码里必须修正的错误
你的代码现在编译都通不过,更别说运行了,这几个问题得先改:
1. flatten方法参数类型不匹配
你在main里调用flatten(df),但flatten方法接收的是JsValue类型,而df是DataFrame,这完全不兼容。正确的做法是把DataFrame的每一行转成JSON字符串,再解析成JsValue后处理:
// 要先导入隐式转换 import sqlContext.implicits._ // 把DataFrame转成JSON字符串的Dataset,再解析成JsValue val jsonDs = df.toJSON.map(Json.parse) // 对每个JsValue执行扁平化 val flattenedDs = jsonDs.map(flatten) // 再转成DataFrame查看结果 val flattenedDf = flattenedDs.map(Json.stringify).toDF("flattened_json") flattenedDf.show()
2. SparkSession构建不完整
代码里val spark = SparkSession.builder().appName("json Reader")没有调用.getOrCreate(),这会导致spark变量不是有效的SparkSession实例,改成:
val spark = SparkSession.builder().appName("json Reader").getOrCreate()
另外Spark 2.x之后推荐用SparkSession代替旧的SQLContext和SparkContext,你可以简化初始化代码:
val spark = SparkSession.builder() .appName("json Reader") .master("local[*]") .getOrCreate() val sqlContext = spark.sqlContext
3. 无用的变量赋值
val set = df.select(...)show()里show()返回的是Unit(无返回值),所以set是没用的变量,改成:
val explodedDf = df.select($"user",$"status",$"reason",explode($"dates").as("date")) explodedDf.show()
三、Spark-submit运行的注意事项
如果打包后用spark-submit运行:
- 明确指定主类:
spark-submit --class json --master local[*] target/your-jar-file.jar(如果有包的话改成--class com.jsonReader.json) - 如果Play JSON依赖没有打包进jar,运行时要通过
--packages引入:spark-submit --class json --packages com.typesafe.play:play-json_2.12:2.8.2 --master local[*] target/your-jar-file.jar
内容的提问来源于stack exchange,提问作者Ashwini Kumar

