Spark Java API写入Avro抛出IllegalArgumentException异常求助
解决Spark Java API写入Avro时的IllegalArgumentException异常
从你的问题描述来看,这个异常只在Java环境下触发,Scala/Spark Shell正常,而且写入文本文件没问题,核心原因大概率是JavaBean反射在Spark分布式环境下的类加载不一致,或者JavaBean本身不符合规范导致的。下面给出几个可行的解决方案:
1. 改用Schema+Row的方式创建DataFrame(推荐)
直接用JavaBean创建DataFrame时,Spark依赖反射来解析字段,但在分布式环境中,Driver和Executor的类加载器可能隔离,导致反射判断对象类型时出现"object is not an instance of declaring class"错误。改用显式定义Schema和Row的方式可以绕开这个问题:
// 1. 定义与bar类对应的Schema StructType schema = DataTypes.createStructType(new StructField[] { DataTypes.createStructField("field1", DataTypes.StringType, true), DataTypes.createStructField("field2", DataTypes.LongType, false), // 依次添加bar类的所有字段,注意类型匹配 }); // 2. 将你的foo集合转换为Row列表 List<Row> rowList = new ArrayList<>(); for (Bar item : foo) { rowList.add(RowFactory.create( item.getField1(), item.getField2() // 对应每个字段的getter调用 )); } // 3. 创建DataFrame并写入Avro DataFrame test = sqlContext.createDataFrame(rowList, schema); test.write().format("com.databricks.spark.avro").save(outLoc);
2. 检查并修复JavaBean的合规性
确保你的bar类严格符合JavaBean规范:
- 拥有public无参构造函数(Spark反射需要实例化对象)
- 所有字段都有对应的public getter方法(比如
getFieldName(),布尔类型用isFieldName()) - 字段类型是可序列化的(比如避免自定义不可序列化的类型)
3. 调整Spark类加载策略
如果是类加载器隔离导致的问题,可以在spark-submit时添加以下参数,让用户类优先加载:
spark-submit \ --conf spark.executor.userClassPathFirst=true \ --conf spark.driver.userClassPathFirst=true \ # 其他参数(jar包、主类等)
这个参数可以避免Spark自带的类和你的项目类发生冲突,确保Driver和Executor加载的bar类是同一个版本。
4. 排查依赖冲突
检查你的Maven依赖,确保spark-avro和Spark版本兼容(你用的spark-avro_2.10:4.0.0确实对应Spark1.6.x),同时排除可能的冲突依赖:
<dependency> <groupId>com.databricks</groupId> <artifactId>spark-avro_2.10</artifactId> <version>4.0.0</version> <exclusions> <exclusion> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.10</artifactId> </exclusion> <exclusion> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.10</artifactId> </exclusion> </exclusions> </dependency>
为什么Scala/Spark Shell没问题?
Scala的反射机制和Java不同,而且Spark Shell环境下Driver和Executor的类加载是统一的,不会出现类隔离的问题;同时Scala Case Class的序列化处理比JavaBean更适配Spark的分布式环境,所以不会触发这个异常。
内容的提问来源于stack exchange,提问作者Tirthankar
相关产品推荐
相关产品推荐

