Spark读取JSON文件抛出ArrayIndexOutOfBoundsException问题求助
Spark读取JSON时ArrayIndexOutOfBoundsException的排查与解决
可能的原因
- JSON文件格式不兼容:Spark默认按单行JSON对象解析,而你提供的是数组格式JSON,若未配置
multiLine参数,解析器会尝试将整个数组当作单行处理,触发索引越界。此外,文件可能存在未闭合的引号/括号、超长字段内容,也会导致解析器内部数组越界。 - Spark版本解析bug:旧版本Spark(如2.x部分版本)在处理复杂嵌套JSON或特殊字符时,存在已知的解析器数组越界问题。
- 文件损坏:JSON文件在写入过程中被中断,导致内容截断、乱码,解析时触发索引错误。
解决方法
1. 适配JSON格式读取配置
如果你的JSON文件是数组结构(如示例),必须开启multiLine参数让Spark正确解析整个数组:
val eventDS = sparkSession.read .option("multiLine", true) // 关键配置,支持多行数组格式JSON .json("src/main/resources/output/intermediateOutput.json")
2. 校验并修复JSON文件
使用jq工具(本地命令行工具)快速校验文件格式:
jq . src/main/resources/output/intermediateOutput.json
若输出报错,根据提示定位并修复JSON语法错误(如未闭合的引号、缺失的逗号等)。如果存在超长字段,可尝试先读取为文本再手动解析:
import org.apache.spark.sql.functions.{col, from_json} import org.apache.spark.sql.types._ // 定义目标Schema val eventSchema = StructType(Seq( StructField("modelName", StringType), StructField("docKey", StringType), StructField("isUpdate", BooleanType), StructField("isUpsert", BooleanType), StructField("etlTime", LongType), StructField("etlTimeHuman", StringType), StructField("accountId", StringType), StructField("timeStamp", LongType), StructField("doc", StructType(Seq( StructField("campaignId", LongType), StructField("engagementId", LongType), StructField("skillId", LongType), StructField("rule", StringType), StructField("action", StringType), StructField("actionCount", LongType), StructField("timeInState", LongType), StructField("eventType", StringType), StructField("reportTime", StringType) ))) )) // 先读取为文本,再手动解析JSON val rawTextDF = sparkSession.read.text("src/main/resources/output/intermediateOutput.json") val eventDS = rawTextDF .select(from_json(col("value"), eventSchema).alias("event")) .select("event.*")
3. 定位错误行并修复
开启failFast参数,让Spark在遇到第一个错误行时抛出详细异常,快速定位问题位置:
val eventDS = sparkSession.read .option("multiLine", true) .option("failFast", true) // 遇到错误立即终止并输出详细信息 .json("src/main/resources/output/intermediateOutput.json")
4. 升级Spark版本
若使用的是Spark 2.x及更早版本,建议升级到Spark 3.x稳定版,新版本修复了大量JSON解析器的已知bug,包括数组越界问题。
验证步骤
- 用
jq工具确认JSON文件格式无语法错误; - 添加
multiLine配置后重新运行代码,观察是否正常读取; - 若仍报错,开启
failFast定位错误行,针对性修复文件内容; - 必要时升级Spark版本重试。
内容的提问来源于stack exchange,提问作者shaheer01
相关产品推荐
相关产品推荐

